mirror of
https://github.com/impact-eintr/netstack.git
synced 2025-10-06 05:16:50 +08:00
156 lines
4.6 KiB
Go
156 lines
4.6 KiB
Go
package tcpip
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
type Error struct {
|
|
msg string
|
|
ignoreStats bool
|
|
}
|
|
|
|
func (e *Error) String() string {
|
|
return e.msg
|
|
}
|
|
|
|
func (e *Error) IgnoreStats() bool {
|
|
return e.ignoreStats
|
|
}
|
|
|
|
var (
|
|
ErrUnknownProtocol = &Error{msg: "unknown protocol"}
|
|
ErrUnknownNICID = &Error{msg: "unknown nic id"}
|
|
ErrUnknownProtocolOption = &Error{msg: "unknown option for protocol"}
|
|
ErrDuplicateNICID = &Error{msg: "duplicate nic id"}
|
|
ErrDuplicateAddress = &Error{msg: "duplicate address"}
|
|
ErrNoRoute = &Error{msg: "no route"}
|
|
ErrBadLinkEndpoint = &Error{msg: "bad link layer endpoint"}
|
|
ErrAlreadyBound = &Error{msg: "endpoint already bound", ignoreStats: true}
|
|
ErrInvalidEndpointState = &Error{msg: "endpoint is in invalid state"}
|
|
ErrAlreadyConnecting = &Error{msg: "endpoint is already connecting", ignoreStats: true}
|
|
ErrAlreadyConnected = &Error{msg: "endpoint is already connected", ignoreStats: true}
|
|
ErrNoPortAvailable = &Error{msg: "no ports are available"}
|
|
ErrPortInUse = &Error{msg: "port is in use"}
|
|
ErrBadLocalAddress = &Error{msg: "bad local address"}
|
|
ErrClosedForSend = &Error{msg: "endpoint is closed for send"}
|
|
ErrClosedForReceive = &Error{msg: "endpoint is closed for receive"}
|
|
ErrWouldBlock = &Error{msg: "operation would block", ignoreStats: true}
|
|
ErrConnectionRefused = &Error{msg: "connection was refused"}
|
|
ErrTimeout = &Error{msg: "operation timed out"}
|
|
ErrAborted = &Error{msg: "operation aborted"}
|
|
ErrConnectStarted = &Error{msg: "connection attempt started", ignoreStats: true}
|
|
ErrDestinationRequired = &Error{msg: "destination address is required"}
|
|
ErrNotSupported = &Error{msg: "operation not supported"}
|
|
ErrQueueSizeNotSupported = &Error{msg: "queue size querying not supported"}
|
|
ErrNotConnected = &Error{msg: "endpoint not connected"}
|
|
ErrConnectionReset = &Error{msg: "connection reset by peer"}
|
|
ErrConnectionAborted = &Error{msg: "connection aborted"}
|
|
ErrNoSuchFile = &Error{msg: "no such file"}
|
|
ErrInvalidOptionValue = &Error{msg: "invalid option value specified"}
|
|
ErrNoLinkAddress = &Error{msg: "no remote link address"}
|
|
ErrBadAddress = &Error{msg: "bad address"}
|
|
ErrNetworkUnreachable = &Error{msg: "network is unreachable"}
|
|
ErrMessageTooLong = &Error{msg: "message too long"}
|
|
ErrNoBufferSpace = &Error{msg: "no buffer space available"}
|
|
)
|
|
|
|
// Clock 提供当前的时间戳
|
|
type Clock interface {
|
|
NowNanoseconds() int64
|
|
|
|
NowMonotonic() int64
|
|
}
|
|
|
|
// 地址是一个字节切片,转换为表示网络节点地址的字符串。或者,在 unix 端点的情况下,它可能代表一条路径
|
|
type Address string
|
|
|
|
type AddressMask string
|
|
|
|
// 传输层的完整地址
|
|
type FullAddress struct {
|
|
NIC NICID // NICID
|
|
Addr Address // IP Address
|
|
Port uint16 // transport Port
|
|
}
|
|
|
|
func (a AddressMask) String() string {
|
|
return Address(a).String()
|
|
}
|
|
|
|
type Subnet struct {
|
|
address Address
|
|
mask AddressMask
|
|
}
|
|
|
|
// LinkAddress 是一个字节切片,转换为表示链接地址的字符串。
|
|
// 它通常是一个 6 字节的 MAC 地址。
|
|
type LinkAddress string // MAC地址
|
|
|
|
type LinkEndpointID uint64
|
|
|
|
type TransportProtocolNumber uint32
|
|
|
|
type NetworkProtocolNumber uint32
|
|
|
|
type NICID int32
|
|
|
|
type Route struct {
|
|
Destination Address // 目标地址
|
|
Mask AddressMask // 掩码
|
|
Gateway Address // 网关
|
|
MIC NICID // 使用的网卡设备
|
|
}
|
|
|
|
// Stats 包含了网络栈的统计信息
|
|
type Stats struct {
|
|
// TODO 需要添加
|
|
}
|
|
|
|
func (a Address) String() string {
|
|
switch len(a) {
|
|
case 4:
|
|
fmt.Println(string(a))
|
|
return fmt.Sprintf("%d.%d.%d.%d", int(a[0]), int(a[1]), int(a[2]), int(a[3]))
|
|
case 16:
|
|
fmt.Println(string(a))
|
|
// Find the longest subsequence of hexadecimal zeros.
|
|
start, end := -1, -1
|
|
for i := 0; i < len(a); i += 2 {
|
|
j := i
|
|
for j < len(a) && a[j] == 0 && a[j+1] == 0 {
|
|
j += 2
|
|
}
|
|
if j > i+2 && j-i > end-start {
|
|
start, end = i, j
|
|
}
|
|
}
|
|
var b strings.Builder
|
|
for i := 0; i < len(a); i += 2 {
|
|
if i == start {
|
|
b.WriteString("::")
|
|
i = end
|
|
if end >= len(a) {
|
|
break
|
|
}
|
|
} else if i > 0 {
|
|
b.WriteByte(':')
|
|
}
|
|
v := uint16(a[i+0])<<8 | uint16(a[i+1])
|
|
if v == 0 {
|
|
b.WriteByte('0')
|
|
} else {
|
|
const digits = "0123456789abcdef"
|
|
for i := uint(3); i < 4; i-- {
|
|
if v := v >> (i * 4); v != 0 {
|
|
b.WriteByte(digits[v&0xf])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return b.String()
|
|
default:
|
|
return fmt.Sprintf("%x", []byte(a))
|
|
}
|
|
}
|