This commit is contained in:
2023-10-27 18:45:33 +02:00
parent abde7e4f10
commit f0f74c2cb5
24 changed files with 1469 additions and 0 deletions

View File

@@ -0,0 +1,94 @@
package Protocols
import (
"encoding/binary"
"github.com/sabouaram/GoNetDev/Protocols/Const_Fields"
"github.com/sabouaram/GoNetDev/Protocols/Utils"
"net"
"strconv"
"strings"
)
type ARP struct {
HardwareType []byte
ProtocolType []byte
HardwareSize []byte
ProtocolSize []byte
Operation []byte
SenderMACaddress []byte
SenderIPaddress []byte
TargetMACaddress []byte
TargetIPaddress []byte
}
func NewArpHeader() *ARP {
return &ARP{}
}
func (Arp *ARP) BuildARPHeader(HardwareType uint16, ProtocolType uint16, SenderIP string, TargetIP string, SenderMACaddress string, TargetMACaddress string, Operation uint16) {
if HardwareType == Const_Fields.Hardware_type_Ethernet && ProtocolType == Const_Fields.Type_IPV4 {
arp_header := []byte{0x00, 0x00, 0x00, 0x00, Const_Fields.ARP_ETH_HARDWARE_SIZE, Const_Fields.ARP_IPV4_PROTOCOL_SIZE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
Arp.HardwareType = arp_header[0:2]
Arp.ProtocolType = arp_header[2:4]
Arp.HardwareSize = arp_header[4:5]
Arp.ProtocolSize = arp_header[5:6]
Arp.Operation = arp_header[6:8]
Arp.SenderMACaddress = arp_header[8:14]
Arp.SenderIPaddress = arp_header[14:18]
Arp.TargetMACaddress = arp_header[18:24]
Arp.TargetIPaddress = arp_header[24:28]
binary.BigEndian.PutUint16(Arp.HardwareType, HardwareType)
binary.BigEndian.PutUint16(Arp.ProtocolType, ProtocolType)
IPsender := net.ParseIP(SenderIP).To4()
IPtarget := net.ParseIP(TargetIP).To4()
for i, v := range IPsender {
Arp.SenderIPaddress[i] = v
}
for i, v := range IPtarget {
Arp.TargetIPaddress[i] = v
}
for i, v := range strings.Split(SenderMACaddress, ":") {
s_byte, _ := strconv.ParseUint(v, 16, 8)
Arp.SenderMACaddress[i] = byte(s_byte)
}
if Operation == Const_Fields.ARP_Operation_request {
binary.BigEndian.PutUint16(Arp.Operation, Operation)
Arp.TargetMACaddress = []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
} else if Operation == Const_Fields.ARP_Operation_reply {
binary.BigEndian.PutUint16(Arp.Operation, Operation)
for i, v := range strings.Split(SenderMACaddress, ":") {
s_byte, _ := strconv.ParseUint(v, 16, 8)
binary.PutUvarint(Arp.TargetMACaddress[i:], s_byte)
}
}
}
}
func (arp *ARP) ARPBytes() []byte {
return Utils.ConcatAppend([][]byte{arp.HardwareType, arp.ProtocolType, arp.HardwareSize, arp.ProtocolSize, arp.Operation, arp.SenderMACaddress, arp.SenderIPaddress, arp.TargetMACaddress, arp.TargetIPaddress})
}
func (arp *ARP) GetTargetMAC() []byte {
return arp.TargetMACaddress
}
func (arp *ARP) SetTargetMAC(MAC []byte) {
arp.TargetMACaddress = []byte{}
arp.TargetMACaddress = MAC
}
func (arp *ARP) ParseARP(arp_byte_slice []byte) {
arp.HardwareType = arp_byte_slice[0:2]
arp.ProtocolType = arp_byte_slice[2:4]
arp.HardwareSize = arp_byte_slice[4:5]
arp.ProtocolSize = arp_byte_slice[5:6]
arp.Operation = arp_byte_slice[6:8]
arp.SenderMACaddress = arp_byte_slice[8:14]
arp.SenderIPaddress = arp_byte_slice[14:18]
arp.TargetMACaddress = arp_byte_slice[18:24]
arp.TargetIPaddress = arp_byte_slice[24:28]
}

View File

@@ -0,0 +1,9 @@
package Const_Fields
const (
ARP_Operation_request = 0x0001
ARP_Operation_reply = 0x0002
Hardware_type_Ethernet = 0x0001
ARP_ETH_HARDWARE_SIZE = 0x06
ARP_IPV4_PROTOCOL_SIZE = 0x04
)

View File

@@ -0,0 +1,9 @@
package Const_Fields
const (
Type_TCP = 0x06
Type_UDP = 0x11
Type_ICMP = 0x01
Type_IPV4 = 0x0800
Type_ARP = 0x0806
)

View File

@@ -0,0 +1,15 @@
package Const_Fields
const (
ICMP_Type_Unreachable = 0x03
ICMP_Type_Exceeded = 0x0b
ICMP_Type_Paremeter_problem = 0x0c
ICMP_Type_Source_quench = 0x04
ICMP_Type_Redirect = 0x05
ICMP_Type_Echo = 0x08
ICMP_Type_Reply = 0x00
ICMP_Type_Timestamp = 0x0d
ICMP_Type_TimestampReply = 0x0e
ICMP_Type_InformationRequest = 0x0f
ICMP_Type_InformationReply = 0x10
)

View File

@@ -0,0 +1,34 @@
package Const_Fields
const (
Version_Hl_IPV4 = 0x45
TTL = 0xff
/*Classes (PHBs) COMBINED WITH ECN(2 bits set to 0) */
DS = 0x00 //BEST EFFORT
DS_ExpeditedForwarding= 0xb8
DS_AF1 = 0x20
DS_AF2 = 0x40
DS_AF3 = 0x60
DS_AF4 = 0x80
DS_NetworkControl = 0xc0
/*Assuring Forwarding class 1 */
DS_AF11 = 0x28 // Low drop prec
DS_AF12 = 0x30 // Medium drop prec
DS_AF13 = 0x38 // High drop prec
/*Assuring Forwarding class 2 */
DS_AF21 = 0x48 // Low drop prec
DS_AF22 = 0x50 // Medium drop prec
DS_AF23 = 0x58 // High drop prec
/*Assuring Forwarding class 3 */
DS_AF31 = 0x68 // Low drop prec
DS_AF32 = 0x70 // Medium drop prec
DS_AF33 = 0x78 // High drop prec
/*Assuring Forwarding class 4 */
DS_AF41 = 0x88 // Low drop prec
DS_AF42 = 0x90 // Medium drop prec
DS_AF43 = 0x98 // High drop prec
)

View File

@@ -0,0 +1,52 @@
package Protocols
import (
"encoding/binary"
"github.com/sabouaram/GoNetDev/Protocols/Const_Fields"
"github.com/sabouaram/GoNetDev/Protocols/Utils/GLogger"
)
func Parse(byte_slice []byte) Frame {
logger := GLogger.GetInstance()
EthHeader := NewEthHeader()
IPHeader := NewIpv4Header()
ARPHeader := NewArpHeader()
ICMPHeader := NewICMPHeader()
padding := 0
Tag1q := binary.BigEndian.Uint16(byte_slice[12:14])
logger.Println(Tag1q)
//In case of a Trunk link
if Tag1q == 33024 {
padding = 4
EthHeader.ParseEthernet(byte_slice, true)
} else {
EthHeader.ParseEthernet(byte_slice, false)
}
logger.Printf("=>ETHERNET: SRC_MAC_ADDRESS:%x, DST_MAC_ADDRESS:%x \n", EthHeader.SourceMacAddress, EthHeader.DestMacAddress)
switch binary.BigEndian.Uint16(EthHeader.Type) {
case Const_Fields.Type_IPV4:
{
IPHeader.ParseIPV4(byte_slice[padding+14:])
logger.Printf(" =>IPV4: SRC_IP_ADDRESS:%x, DST_IP_ADDRESS:%x \n", IPHeader.Src_address, IPHeader.Dst_address)
switch uint8(IPHeader.Protocol[0]) {
case Const_Fields.Type_ICMP:
ICMPHeader.ParseICMP(byte_slice[padding+34:])
logger.Println(" =>ICMP")
case Const_Fields.Type_TCP:
logger.Println(" =>TCP")
case Const_Fields.Type_UDP:
logger.Println(" =>UDP")
}
}
case 0x0806:
{
ARPHeader.ParseARP(byte_slice[padding+14:])
logger.Printf(" =>ARP: SRC_MAC_ADDRESS:%x, SRC_IP_ADDRESS:%x , TARGET_MAC_ADDRESS:%x, TARGET_IP_ADDRESS:%x, Operation: %x \n", ARPHeader.SenderMACaddress, ARPHeader.SenderIPaddress, ARPHeader.TargetMACaddress, ARPHeader.TargetIPaddress, ARPHeader.Operation)
}
}
return Frame{EthHeader, ARPHeader, IPHeader, ICMPHeader}
}

View File

@@ -0,0 +1,95 @@
package Protocols
import (
"encoding/binary"
"fmt"
"github.com/sabouaram/GoNetDev/Protocols/Utils"
"math/bits"
"reflect"
"strconv"
"strings"
)
type Ethernet struct {
DestMacAddress []byte
SourceMacAddress []byte
Dot1Q []byte
Type []byte
}
func NewEthHeader() (Eth_header *Ethernet) {
return &Ethernet{}
}
func (Header *Ethernet) BuildHeader(destmac string, src string, ntype uint16) {
header := make([]byte, 18)
Header.DestMacAddress = header[0:6]
Header.SourceMacAddress = header[6:12]
Header.Dot1Q = header[12:16]
Header.Dot1Q = []byte{}
Header.Type = header[16:18]
if len(strings.Split(destmac, ":")) != 6 || len(strings.Split(src, ":")) != 6 {
}
hex_macs_string := append(strings.Split(destmac, ":"), strings.Split(src, ":")...)
for i, v := range hex_macs_string {
i_byte, err := strconv.ParseUint(v, 16, 8)
if err == nil {
binary.PutUvarint(header[i:], i_byte)
}
}
binary.BigEndian.PutUint16(Header.Type, ntype)
}
func (Header *Ethernet) EthernetBytes() []byte {
sRValue := reflect.ValueOf(Header).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)
}
func (Header *Ethernet) ParseEthernet(byte_slice []byte, isTrunked bool) {
if isTrunked {
Header.DestMacAddress = byte_slice[0:6]
Header.SourceMacAddress = byte_slice[6:12]
Header.Dot1Q = byte_slice[12:16]
Header.Type = byte_slice[16:18]
} else {
Header.DestMacAddress = byte_slice[0:6]
Header.SourceMacAddress = byte_slice[6:12]
Header.Type = byte_slice[12:14]
}
}
func (Header *Ethernet) TagDot1Q(VlanID int64, Priority int64) {
TPID_s := fmt.Sprintf("%16b", 0x8100)
PRI_s := fmt.Sprintf("%03b", Priority)
CFI_s := fmt.Sprintf("%1b", 0)
VID_s := fmt.Sprintf("%012b", VlanID)
Tag, _ := strconv.ParseUint(TPID_s+PRI_s+CFI_s+VID_s, 2, 32)
Tag_slice := make([]byte, 4)
binary.BigEndian.PutUint32(Tag_slice, uint32(Tag))
Header.Dot1Q = []byte{}
Header.Dot1Q = append(Tag_slice)
}
func (Header *Ethernet) GetVlanID() (vlanid int64) {
last2bytes := binary.BigEndian.Uint16(Header.Dot1Q[2:])
vlanId, _ := strconv.ParseUint(fmt.Sprintf("%016b \n", bits.RotateLeft16(last2bytes, 4))[0:12], 2, 12)
return int64(vlanId)
}
func (Header *Ethernet) GetPriority() (priority int64) {
last2bytes := binary.BigEndian.Uint16(Header.Dot1Q[2:])
Priority, _ := strconv.ParseUint(fmt.Sprintf("%03b \n", bits.RotateLeft16(last2bytes, 0))[0:3], 2, 3)
return int64(Priority)
}

View File

@@ -0,0 +1,60 @@
package Protocols
import (
"github.com/sabouaram/GoNetDev/Protocols/Utils"
"reflect"
)
var Buffer_Channel chan Frame
type Frame struct {
Eth *Ethernet
Arph *ARP
Iph *IP
Icmph *ICMP
/*others*/
}
func NewFrame() *Frame {
frame := Frame{}
frame.Eth = NewEthHeader()
frame.Arph = NewArpHeader()
frame.Iph = NewIpv4Header()
frame.Icmph = NewICMPHeader()
return &frame
}
func (frame *Frame) FrameBytes() (byte_array []byte) {
sRValue := reflect.ValueOf(frame).Elem()
sRType := sRValue.Type()
array := [][]byte{}
for i := 0; i < sRType.NumField(); i++ {
value := sRValue.Field(i).Interface()
switch sRType.Field(i).Name {
case "Eth":
{
eth, _ := value.(*Ethernet)
array = append(array, eth.EthernetBytes())
}
case "Arph":
{
arph, _ := value.(*ARP)
array = append(array, arph.ARPBytes())
}
case "Iph":
{
iph, _ := value.(*IP)
array = append(array, iph.IPV4Bytes())
}
case "Icmph":
{
icmph, _ := value.(*ICMP)
array = append(array, icmph.ICMPBytes())
}
}
}
return Utils.ConcatAppend(array)
}

View File

@@ -0,0 +1,179 @@
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)
}

View File

@@ -0,0 +1,147 @@
package Protocols
import (
"encoding/binary"
"fmt"
"github.com/sabouaram/GoNetDev/Protocols/Const_Fields"
"github.com/sabouaram/GoNetDev/Protocols/Utils"
"math"
"net"
"strconv"
)
// RFC 791 INTERNET PROTOCOL VERSION 4
/* Developer: Salim BOU ARAM, e-mail: salimbouaram12@gmail.com */
type IP struct {
Version_HL []byte
DS []byte
Total_Length []byte
Identification []byte
Flags []byte
TTL []byte
Protocol []byte
Header_checksum []byte
Src_address []byte
Dst_address []byte
}
type Packet struct {
IPH *IP
Data []byte
}
func NewIpv4Header() (header *IP) {
return &IP{}
}
func (Ip *IP) BuildIPV4Header(IPsrc string, IPdest string, Protocol uint8) {
IPheader := []byte{Const_Fields.Version_Hl_IPV4, Const_Fields.DS, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, Const_Fields.TTL, Protocol, 0x00, 0x00}
Ip.Version_HL = IPheader[0:1]
Ip.DS = IPheader[1:2]
Ip.Total_Length = IPheader[2:4]
Ip.Identification = IPheader[4:6]
Ip.Flags = IPheader[6:8]
Ip.TTL = IPheader[8:9]
Ip.Protocol = IPheader[9:10]
Ip.Header_checksum = IPheader[10:12]
Ip.Src_address = net.ParseIP(IPsrc).To4()
Ip.Dst_address = net.ParseIP(IPdest).To4()
Ip.HeaderChecksum()
}
func (Header *IP) IPV4Bytes() []byte {
return Utils.ConcatAppend([][]byte{Header.Version_HL, Header.DS, Header.Total_Length, Header.Identification, Header.Flags, Header.TTL, Header.Protocol, Header.Header_checksum, Header.Src_address, Header.Dst_address})
}
func Fragment(data []byte, MTU int, Protocol uint8, IPsrc string, IPdest string) (Packets map[int]Packet) {
results := make(map[int]Packet)
data_size := len(data)
fragment_count := int(math.Ceil(float64(data_size) / float64(MTU)))
offset := 0
Identification_bits := uint16(0x0000) // Initialize Identification_bits
for k := 0; k < fragment_count; k++ {
IP := NewIpv4Header()
IP.BuildIPV4Header(IPsrc, IPdest, Protocol)
IP.SetSRC(IPsrc)
IP.SetDST(IPdest)
Total_Length := 20
var flags_hex uint16
if k < fragment_count-1 {
IP.Total_Length = []byte{uint8(uint16(Total_Length+MTU-34) >> 8), uint8(uint16(Total_Length+MTU-34) & 0xff)}
IP.Identification = []byte{uint8(Identification_bits >> 8), uint8(Identification_bits & 0xff)}
flags_hex = uint16(0x2000) // More fragments
Identification_bits++
} else {
IP.Total_Length = []byte{uint8(uint16(Total_Length+data_size-offset) >> 8), uint8(uint16(Total_Length+data_size-offset) & 0xff)}
IP.Identification = []byte{uint8(Identification_bits >> 8), uint8(Identification_bits & 0xff)}
flags_hex = uint16(0x0000) // Last fragment
}
IP.Flags = []byte{uint8(flags_hex >> 8), uint8(flags_hex & 0xff)}
IP.HeaderChecksum()
fragmentSize := MTU - 34
if k == fragment_count-1 {
fragmentSize = data_size - offset
}
results[k] = Packet{IP, data[offset : offset+fragmentSize]}
offset += fragmentSize
}
return results
}
func (Header *IP) HeaderChecksum() {
intsum := int64(0)
header_bytes := Header.IPV4Bytes()
for i := 0; i <= 18; i += 2 {
hex_string_2 := fmt.Sprintf("%x", header_bytes[i:i+2])
uintsumf, _ := strconv.ParseUint(hex_string_2, 16, 16)
intsum += int64(uintsumf)
if intsum > 65536 {
intsum -= 65536
}
}
header_cheksum := uint16(intsum) ^ 0xffff
binary.BigEndian.PutUint16(Header.Header_checksum, header_cheksum)
}
func (Header *IP) SetSRC(ipstring string) {
Header.Src_address = []byte{}
Header.Src_address = net.ParseIP(ipstring).To4()
}
func (Header *IP) SetDST(ipstring string) {
Header.Dst_address = []byte{}
Header.Dst_address = net.ParseIP(ipstring).To4()
}
func (Header *IP) ReverseSrc() {
ipdst := Header.Dst_address
Header.Dst_address = Header.Src_address
Header.Src_address = ipdst
}
func (Header *IP) GetProtocol() uint8 {
return Header.Protocol[0]
}
func (Header *IP) SetDS(label uint8) {
Header.DS = []byte{}
Header.DS = append(Header.DS, label)
}
func (Header *IP) ParseIPV4(byte_slice []byte) {
Header.Version_HL = byte_slice[0:1]
Header.DS = byte_slice[1:2]
Header.Total_Length = byte_slice[2:4]
Header.Identification = byte_slice[4:6]
Header.Flags = byte_slice[6:8]
Header.TTL = byte_slice[8:9]
Header.Protocol = byte_slice[9:10]
Header.Header_checksum = byte_slice[10:12]
Header.Src_address = byte_slice[12:16]
Header.Dst_address = byte_slice[16:20]
}

View File

@@ -0,0 +1,28 @@
package Protocols
import "github.com/sabouaram/GoNetDev/Protocols/Const_Fields"
//Layer2(Cos)/Layer3(dscp) mapping in L2L3QoSMap:
//================================
//802.1p: 0 1 2 3 4 5 6 7
//----------------------------
//dscp: 0 8 16 24 32 46 48 56 *
func QoSMapping() map[int64]uint8 {
L2L3QoSMap := map[int64]uint8{
0: Const_Fields.DS, //BEST EFFORT CLASS
1: Const_Fields.DS_AF1, //AF1 CLASS
2: Const_Fields.DS_AF2, //AF2 CLASS
3: Const_Fields.DS_AF3, //AF3 CLASS
4: Const_Fields.DS_AF4, //AF4 CLASS
5: Const_Fields.DS_ExpeditedForwarding, //ExpeditedForwarding
6: Const_Fields.DS_NetworkControl, //Network control
}
return L2L3QoSMap
}
func (frame *Frame) LabelIPH(DS uint8) {
frame.Iph.SetDS(DS)
}
// Function For marking

View File

@@ -0,0 +1,72 @@
package SendRecv
import (
"github.com/sabouaram/GoNetDev/Protocols"
"github.com/sabouaram/GoNetDev/Protocols/Utils"
"github.com/sabouaram/GoNetDev/Protocols/Utils/GLogger"
"net"
"syscall"
)
func SyscallRawEth() (fd int) {
fd, error := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, 0x0300)
if error != nil {
syscall.Close(fd)
panic(error)
}
return fd
}
func ReceiveFrame(interface_name string, byte_size int, chn chan Protocols.Frame) error {
fd := SyscallRawEth()
err := syscall.BindToDevice(fd, interface_name)
if err != nil {
syscall.Close(fd)
panic(err)
}
buffer := make([]byte, byte_size)
logger := GLogger.GetInstance()
logger.Printf("RX:%s", interface_name)
Frames_received_metric := Utils.NewPromCounter("frames_received", "frames received per interface", []string{"interface_name"})
Utils.Register(Frames_received_metric)
for true {
syscall.Recvfrom(fd, buffer, 0)
Frame := Protocols.Parse(buffer)
chn <- Frame
Frames_received_metric.With(Utils.NewLabel("interface_name", interface_name)).Inc()
logger.Printf("RX:%s", interface_name)
}
return nil
}
func SendFrame(interface_name string, frame []byte) (count_bytes int, err error) {
fd := SyscallRawEth()
interface_info, err := net.InterfaceByName(interface_name)
if err != nil {
return 0, err
}
var haddr [8]byte
copy(haddr[0:7], interface_info.HardwareAddr[0:7])
addr := syscall.SockaddrLinklayer{
Protocol: syscall.ETH_P_IP,
Ifindex: interface_info.Index,
Halen: uint8(len(interface_info.HardwareAddr)),
Addr: haddr,
}
err = syscall.Bind(fd, &addr)
if err != nil {
return 0, err
}
err = syscall.SetLsfPromisc(interface_name, true)
if err != nil {
return 0, err
}
n, err := syscall.Write(fd, frame)
if err != nil {
return 0, err
}
return n, err
}

View File

@@ -0,0 +1,9 @@
package Utils
func ConcatAppend(slices [][]byte) []byte {
var tmp []byte
for _, s := range slices {
tmp = append(tmp, s...)
}
return tmp
}

View File

@@ -0,0 +1,32 @@
package GLogger
import (
"sync"
"log"
"os"
"io"
)
var once sync.Once
var Glogger *GLogger
type GLogger struct {
*log.Logger
filename string
}
func GetInstance() *GLogger {
once.Do(func() {
Glogger = createLogger("/var/log/Gonetdev.log")
})
return Glogger
}
func createLogger(fname string) *GLogger {
file, _ := os.OpenFile(fname,os.O_CREATE | os.O_APPEND | os.O_RDWR, 0666)
mw := io.MultiWriter(os.Stdout, file)
return &GLogger{
filename: fname,
Logger: log.New(mw, "", log.Lshortfile),
}
}

View File

@@ -0,0 +1,34 @@
package Utils
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"log"
"net/http"
)
func init() {
go func() {
http.Handle("/metrics", promhttp.Handler())
log.Fatal(http.ListenAndServe(": 8080", nil))
}()
}
func NewPromCounter(metric string, help_msg string, labels []string) *prometheus.CounterVec {
return prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: metric,
Help: help_msg,
},
labels,
)
}
func NewLabel(lblkey string, lblvalue string) prometheus.Labels {
return prometheus.Labels{lblkey: lblvalue}
}
func Register(c prometheus.Collector) {
prometheus.MustRegister(c)
}