mirror of
https://github.com/impact-eintr/netstack.git
synced 2025-10-06 05:16:50 +08:00
网卡对象 绑定IP地址 然后向网卡对象写入数据 数据中将包含dst和src
This commit is contained in:
162
tcpip/tcpip.go
162
tcpip/tcpip.go
@@ -1,8 +1,11 @@
|
||||
package tcpip
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
type Error struct {
|
||||
@@ -55,6 +58,12 @@ var (
|
||||
ErrNoBufferSpace = &Error{msg: "no buffer space available"}
|
||||
)
|
||||
|
||||
// Errors related to Subnet
|
||||
var (
|
||||
errSubnetLengthMismatch = errors.New("subnet length of address and mask differ")
|
||||
errSubnetAddressMasked = errors.New("subnet address has bits set outside the mask")
|
||||
)
|
||||
|
||||
// Clock 提供当前的时间戳
|
||||
type Clock interface {
|
||||
NowNanoseconds() int64
|
||||
@@ -83,6 +92,70 @@ type Subnet struct {
|
||||
mask AddressMask
|
||||
}
|
||||
|
||||
// NewSubnet creates a new Subnet, checking that the address and mask are the same length.
|
||||
func NewSubnet(a Address, m AddressMask) (Subnet, error) {
|
||||
if len(a) != len(m) {
|
||||
return Subnet{}, errSubnetLengthMismatch
|
||||
}
|
||||
for i := 0; i < len(a); i++ {
|
||||
if a[i]&^m[i] != 0 {
|
||||
return Subnet{}, errSubnetAddressMasked
|
||||
}
|
||||
}
|
||||
return Subnet{a, m}, nil
|
||||
}
|
||||
|
||||
// Contains returns true iff the address is of the same length and matches the
|
||||
// subnet address and mask.
|
||||
func (s *Subnet) Contains(a Address) bool {
|
||||
if len(a) != len(s.address) {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(a); i++ {
|
||||
if a[i]&s.mask[i] != s.address[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ID returns the subnet ID.
|
||||
func (s *Subnet) ID() Address {
|
||||
return s.address
|
||||
}
|
||||
|
||||
// Bits returns the number of ones (network bits) and zeros (host bits) in the
|
||||
// subnet mask.
|
||||
func (s *Subnet) Bits() (ones int, zeros int) {
|
||||
for _, b := range []byte(s.mask) {
|
||||
for i := uint(0); i < 8; i++ {
|
||||
if b&(1<<i) == 0 {
|
||||
zeros++
|
||||
} else {
|
||||
ones++
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Prefix returns the number of bits before the first host bit.
|
||||
func (s *Subnet) Prefix() int {
|
||||
for i, b := range []byte(s.mask) {
|
||||
for j := 7; j >= 0; j-- {
|
||||
if b&(1<<uint(j)) == 0 {
|
||||
return i*8 + 7 - j
|
||||
}
|
||||
}
|
||||
}
|
||||
return len(s.mask) * 8
|
||||
}
|
||||
|
||||
// Mask returns the subnet mask.
|
||||
func (s *Subnet) Mask() AddressMask {
|
||||
return s.mask
|
||||
}
|
||||
|
||||
// LinkAddress 是一个字节切片,转换为表示链接地址的字符串。
|
||||
// 它通常是一个 6 字节的 MAC 地址。
|
||||
type LinkAddress string // MAC地址
|
||||
@@ -104,11 +177,96 @@ type Route struct {
|
||||
|
||||
// Stats 包含了网络栈的统计信息
|
||||
type Stats struct {
|
||||
// TODO 需要添加
|
||||
// TODO 需要解读
|
||||
// UnknownProtocolRcvdPackets is the number of packets received by the
|
||||
// stack that were for an unknown or unsupported protocol.
|
||||
UnknownProtocolRcvdPackets *StatCounter
|
||||
|
||||
// MalformedRcvPackets is the number of packets received by the stack
|
||||
// that were deemed malformed.
|
||||
MalformedRcvdPackets *StatCounter
|
||||
|
||||
// DroppedPackets is the number of packets dropped due to full queues.
|
||||
DroppedPackets *StatCounter
|
||||
|
||||
// IP breaks out IP-specific stats (both v4 and v6).
|
||||
IP IPStats
|
||||
|
||||
// TCP breaks out TCP-specific stats.
|
||||
TCP TCPStats
|
||||
|
||||
// UDP breaks out UDP-specific stats.
|
||||
UDP UDPStats
|
||||
}
|
||||
|
||||
// A StatCounter keeps track of a statistic.
|
||||
type StatCounter struct {
|
||||
count uint64
|
||||
}
|
||||
|
||||
// Increment adds one to the counter.
|
||||
func (s *StatCounter) Increment() {
|
||||
s.IncrementBy(1)
|
||||
}
|
||||
|
||||
// Value returns the current value of the counter.
|
||||
func (s *StatCounter) Value() uint64 {
|
||||
return atomic.LoadUint64(&s.count)
|
||||
}
|
||||
|
||||
// IncrementBy increments the counter by v.
|
||||
func (s *StatCounter) IncrementBy(v uint64) {
|
||||
atomic.AddUint64(&s.count, v)
|
||||
}
|
||||
|
||||
type IPStats struct {
|
||||
// PacketsReceived is the total number of IP packets received from the link
|
||||
// layer in nic.DeliverNetworkPacket.
|
||||
PacketsReceived *StatCounter
|
||||
|
||||
// InvalidAddressesReceived is the total number of IP packets received
|
||||
// with an unknown or invalid destination address.
|
||||
InvalidAddressesReceived *StatCounter
|
||||
|
||||
// PacketsDelivered is the total number of incoming IP packets that
|
||||
// are successfully delivered to the transport layer via HandlePacket.
|
||||
PacketsDelivered *StatCounter
|
||||
|
||||
// PacketsSent is the total number of IP packets sent via WritePacket.
|
||||
PacketsSent *StatCounter
|
||||
|
||||
// OutgoingPacketErrors is the total number of IP packets which failed
|
||||
// to write to a link-layer endpoint.
|
||||
OutgoingPacketErrors *StatCounter
|
||||
}
|
||||
|
||||
type TCPStats struct{}
|
||||
|
||||
type UDPStats struct{}
|
||||
|
||||
func fillIn(v reflect.Value) {
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
v := v.Field(i)
|
||||
switch v.Kind() {
|
||||
case reflect.Ptr:
|
||||
if s, ok := v.Addr().Interface().(**StatCounter); ok {
|
||||
if *s == nil {
|
||||
*s = &StatCounter{}
|
||||
}
|
||||
}
|
||||
case reflect.Struct:
|
||||
fillIn(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FillIn returns a copy of s with nil fields initialized to new StatCounters.
|
||||
func (s Stats) FillIn() Stats {
|
||||
fillIn(reflect.ValueOf(&s).Elem())
|
||||
return s
|
||||
}
|
||||
|
||||
func (a Address) String() string {
|
||||
fmt.Println(string(a), len(a))
|
||||
switch len(a) {
|
||||
case 4:
|
||||
return fmt.Sprintf("%d.%d.%d.%d", int(a[0]), int(a[1]), int(a[2]), int(a[3]))
|
||||
|
Reference in New Issue
Block a user