mirror of
https://github.com/impact-eintr/netstack.git
synced 2025-10-06 13:26:49 +08:00
NIC 对象绑定IP还未实现完成 明天继续
This commit is contained in:
@@ -1,11 +1,32 @@
|
|||||||
package stack
|
package stack
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"netstack/ilist"
|
"netstack/ilist"
|
||||||
"netstack/tcpip"
|
"netstack/tcpip"
|
||||||
|
"netstack/tcpip/buffer"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// PrimaryEndpointBehavior 是端点首要行为的枚举
|
||||||
|
type PrimaryEndpointBehavior int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// CanBePrimaryEndpoint indicates the endpoint can be used as a primary
|
||||||
|
// endpoint for new connections with no local address. This is the
|
||||||
|
// default when calling NIC.AddAddress.
|
||||||
|
CanBePrimaryEndpoint PrimaryEndpointBehavior = iota
|
||||||
|
|
||||||
|
// FirstPrimaryEndpoint indicates the endpoint should be the first
|
||||||
|
// primary endpoint considered. If there are multiple endpoints with
|
||||||
|
// this behavior, the most recently-added one will be first.
|
||||||
|
FirstPrimaryEndpoint
|
||||||
|
|
||||||
|
// NeverPrimaryEndpoint indicates the endpoint should never be a
|
||||||
|
// primary endpoint.
|
||||||
|
NeverPrimaryEndpoint
|
||||||
|
)
|
||||||
|
|
||||||
// 代表一个网卡对象 当我们创建好tap网卡对象后 我们使用NIC来代表它在我们自己的协议栈中的网卡对象
|
// 代表一个网卡对象 当我们创建好tap网卡对象后 我们使用NIC来代表它在我们自己的协议栈中的网卡对象
|
||||||
type NIC struct {
|
type NIC struct {
|
||||||
stack *Stack
|
stack *Stack
|
||||||
@@ -24,7 +45,57 @@ type NIC struct {
|
|||||||
promiscuous bool // 混杂模式
|
promiscuous bool // 混杂模式
|
||||||
primary map[tcpip.NetworkProtocolNumber]*ilist.List
|
primary map[tcpip.NetworkProtocolNumber]*ilist.List
|
||||||
// 网络层端的记录
|
// 网络层端的记录
|
||||||
endpoints map[NetworkEndpoingID]*referencedNetworkEndpoint
|
endpoints map[NetworkEndpointID]*referencedNetworkEndpoint
|
||||||
// 子网的记录
|
// 子网的记录
|
||||||
subnets []tcpip.Subnet
|
subnets []tcpip.Subnet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 创建新的网卡对象
|
||||||
|
func newNIC(stack *Stack, id tcpip.NICID, name string, ep LinkEndpoint) *NIC {
|
||||||
|
return &NIC{
|
||||||
|
stack: stack,
|
||||||
|
id: id,
|
||||||
|
name: name,
|
||||||
|
linkEP: ep,
|
||||||
|
demux: nil, // TODO 需要处理
|
||||||
|
primary: make(map[tcpip.NetworkProtocolNumber]*ilist.List),
|
||||||
|
endpoints: make(map[NetworkEndpointID]*referencedNetworkEndpoint),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NIC) attachLinkEndpoint() {
|
||||||
|
n.linkEP.Attach(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在NIC上添加addr地址,注册和初始化网络层协议
|
||||||
|
// 相当于给网卡添加ip地址
|
||||||
|
func (n *NIC) addAddressLocked(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address,
|
||||||
|
peb PrimaryEndpointBehavior, replace bool) (*referencedNetworkEndpoint, *tcpip.Error) {
|
||||||
|
netProto, ok := n.stack.networkProtocols[protocol]
|
||||||
|
if !ok {
|
||||||
|
log.Println("添加失败")
|
||||||
|
return nil, tcpip.ErrUnknownProtocol
|
||||||
|
}
|
||||||
|
log.Println(netProto.Number(), "添加ip", addr.String())
|
||||||
|
// TODO 接着这里实现 22/11/24 21:29
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NIC) AddAddress(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address) *tcpip.Error {
|
||||||
|
return n.AddAddressWithOptions(protocol, addr, CanBePrimaryEndpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NIC) AddAddressWithOptions(protocol tcpip.NetworkProtocolNumber,
|
||||||
|
addr tcpip.Address, peb PrimaryEndpointBehavior) *tcpip.Error {
|
||||||
|
n.mu.Lock()
|
||||||
|
_, err := n.addAddressLocked(protocol, addr, peb, false)
|
||||||
|
n.mu.Unlock()
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, dstLinkAddr, srcLinkAddr tcpip.LinkAddress,
|
||||||
|
protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) {
|
||||||
|
// TODO 需要完成逻辑
|
||||||
|
log.Println(vv.ToView())
|
||||||
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package stack
|
package stack
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"netstack/ilist"
|
"netstack/ilist"
|
||||||
"netstack/sleep"
|
"netstack/sleep"
|
||||||
"netstack/tcpip"
|
"netstack/tcpip"
|
||||||
@@ -89,9 +90,16 @@ type NetworkDispatcher interface {
|
|||||||
|
|
||||||
type LinkEndpointCapabilities uint
|
type LinkEndpointCapabilities uint
|
||||||
|
|
||||||
|
// type TransportProtocolFactory func() TransportProtocol TODO
|
||||||
|
|
||||||
|
type NetworkProtocolFactory func() NetworkProtocol
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// 以下两个map需要在init函数中注册
|
||||||
// 传输层协议的注册存储结构 TODO
|
// 传输层协议的注册存储结构 TODO
|
||||||
// 网络层协议的注册存储结构 TODO
|
//transportProtocols = make(map[string]TransportProtocolFactory)
|
||||||
|
// 网络层协议的注册存储结构
|
||||||
|
networkProtocols = make(map[string]NetworkProtocolFactory)
|
||||||
|
|
||||||
linkEPMu sync.RWMutex
|
linkEPMu sync.RWMutex
|
||||||
nextLinkEndpointID tcpip.LinkEndpointID = 1
|
nextLinkEndpointID tcpip.LinkEndpointID = 1
|
||||||
@@ -100,7 +108,8 @@ var (
|
|||||||
|
|
||||||
// ==============================网络层相关==============================
|
// ==============================网络层相关==============================
|
||||||
type NetworkProtocol interface {
|
type NetworkProtocol interface {
|
||||||
// TODO 需要添加
|
Number() tcpip.NetworkProtocolNumber
|
||||||
|
// todo 需要添加
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetworkEndpoint是需要由网络层协议(例如,ipv4,ipv6)的端点实现的接口
|
// NetworkEndpoint是需要由网络层协议(例如,ipv4,ipv6)的端点实现的接口
|
||||||
@@ -108,7 +117,7 @@ type NetworkEndpoint interface {
|
|||||||
// TODO 需要添加
|
// TODO 需要添加
|
||||||
}
|
}
|
||||||
|
|
||||||
type NetworkEndpoingID struct {
|
type NetworkEndpointID struct {
|
||||||
LocalAddress tcpip.Address
|
LocalAddress tcpip.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,6 +156,12 @@ type referencedNetworkEndpoint struct {
|
|||||||
holdsInsertRef bool
|
holdsInsertRef bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 注册一个新的网络协议工厂
|
||||||
|
func RegisterNetworkProtocolFactory(name string, p NetworkProtocolFactory) {
|
||||||
|
networkProtocols[name] = p
|
||||||
|
log.Println(networkProtocols)
|
||||||
|
}
|
||||||
|
|
||||||
// 注册一个链路层设备
|
// 注册一个链路层设备
|
||||||
func RegisterLinkEndpoint(linkEP LinkEndpoint) tcpip.LinkEndpointID {
|
func RegisterLinkEndpoint(linkEP LinkEndpoint) tcpip.LinkEndpointID {
|
||||||
linkEPMu.Lock()
|
linkEPMu.Lock()
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package stack
|
package stack
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"netstack/tcpip"
|
"netstack/tcpip"
|
||||||
"netstack/tcpip/ports"
|
"netstack/tcpip/ports"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -48,6 +49,31 @@ type Stack struct {
|
|||||||
clock tcpip.Clock
|
clock tcpip.Clock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func New(network []string) *Stack {
|
||||||
|
s := &Stack{
|
||||||
|
transportProtocols: make(map[tcpip.TransportProtocolNumber]*transportProtocolState),
|
||||||
|
networkProtocols: make(map[tcpip.NetworkProtocolNumber]NetworkProtocol),
|
||||||
|
linkAddrResolvers: make(map[tcpip.NetworkProtocolNumber]LinkAddressResolver),
|
||||||
|
nics: make(map[tcpip.NICID]*NIC),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加指定的网络端协议 必须已经在init中注册过
|
||||||
|
for _, name := range network {
|
||||||
|
// 先检查这个网络协议是否注册过工厂方法
|
||||||
|
netProtoFactory, ok := networkProtocols[name]
|
||||||
|
if !ok {
|
||||||
|
log.Println(name)
|
||||||
|
continue // 没有就略过
|
||||||
|
}
|
||||||
|
netProto := netProtoFactory() // 制造一个该型号协议的示实例
|
||||||
|
s.networkProtocols[netProto.Number()] = netProto // 注册该型号的网络协议
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加指定的传输层协议 必已经在init中注册过
|
||||||
|
// TODO
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Stack) CreateNIC(id tcpip.NICID, linkEP tcpip.LinkEndpointID) *tcpip.Error {
|
func (s *Stack) CreateNIC(id tcpip.NICID, linkEP tcpip.LinkEndpointID) *tcpip.Error {
|
||||||
return s.createNIC(id, "", linkEP, true)
|
return s.createNIC(id, "", linkEP, true)
|
||||||
}
|
}
|
||||||
@@ -66,10 +92,30 @@ func (s *Stack) createNIC(id tcpip.NICID, name string, linkEP tcpip.LinkEndpoint
|
|||||||
if _, ok := s.nics[id]; ok {
|
if _, ok := s.nics[id]; ok {
|
||||||
return tcpip.ErrDuplicateNICID
|
return tcpip.ErrDuplicateNICID
|
||||||
}
|
}
|
||||||
n := newIC(s, id, name, ep)
|
n := newNIC(s, id, name, ep)
|
||||||
|
|
||||||
s.nics[id] = n
|
s.nics[id] = n
|
||||||
if enable {
|
if enable {
|
||||||
n.attachLinkEndpoint()
|
n.attachLinkEndpoint()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 给网卡添加ip地址
|
||||||
|
func (s *Stack) AddAddress(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber, addr tcpip.Address) *tcpip.Error {
|
||||||
|
return s.AddAddressWithOptions(id, protocol, addr, CanBePrimaryEndpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stack) AddAddressWithOptions(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber,
|
||||||
|
addr tcpip.Address, peb PrimaryEndpointBehavior) *tcpip.Error {
|
||||||
|
s.mu.RLock()
|
||||||
|
defer s.mu.RUnlock()
|
||||||
|
|
||||||
|
nic := s.nics[id]
|
||||||
|
if nic == nil {
|
||||||
|
return tcpip.ErrUnknownNICID
|
||||||
|
}
|
||||||
|
|
||||||
|
return nic.AddAddressWithOptions(protocol, addr, peb)
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,9 @@
|
|||||||
package stack_test
|
package stack_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
|
"netstack/tcpip"
|
||||||
|
"netstack/tcpip/buffer"
|
||||||
"netstack/tcpip/link/channel"
|
"netstack/tcpip/link/channel"
|
||||||
"netstack/tcpip/stack"
|
"netstack/tcpip/stack"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -10,12 +13,33 @@ const (
|
|||||||
defaultMTU = 65536
|
defaultMTU = 65536
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type fakeNetworkProtocol struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fakeNetworkProtocol) Number() tcpip.NetworkProtocolNumber {
|
||||||
|
return 114514
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
stack.RegisterNetworkProtocolFactory("fakeNet", func() stack.NetworkProtocol {
|
||||||
|
return &fakeNetworkProtocol{}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestStackBase(t *testing.T) {
|
func TestStackBase(t *testing.T) {
|
||||||
|
|
||||||
myStack := &stack.Stack{}
|
myStack := stack.New([]string{"fakeNet"})
|
||||||
id, _ := channel.New(10, defaultMTU, "")
|
id, ep := channel.New(10, defaultMTU, "") // 这是一个物理设备
|
||||||
|
log.Println(id)
|
||||||
|
|
||||||
if err := myStack.CreateNIC(1, id); err != nil {
|
if err := myStack.CreateNIC(1, id); err != nil { // 将上面的物理设备抽象成我们的网卡对象
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
myStack.AddAddress(1, 114514, "\x01") // 给网卡对象绑定一个IP地址 可以绑定多个
|
||||||
|
|
||||||
|
buf := buffer.NewView(30)
|
||||||
|
for i := range buf {
|
||||||
|
buf[i] = 1
|
||||||
|
}
|
||||||
|
ep.Inject(114514, buf.ToVectoriseView())
|
||||||
}
|
}
|
||||||
|
@@ -108,12 +108,11 @@ type Stats struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a Address) String() string {
|
func (a Address) String() string {
|
||||||
|
fmt.Println(string(a), len(a))
|
||||||
switch len(a) {
|
switch len(a) {
|
||||||
case 4:
|
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]))
|
return fmt.Sprintf("%d.%d.%d.%d", int(a[0]), int(a[1]), int(a[2]), int(a[3]))
|
||||||
case 16:
|
case 16:
|
||||||
fmt.Println(string(a))
|
|
||||||
// Find the longest subsequence of hexadecimal zeros.
|
// Find the longest subsequence of hexadecimal zeros.
|
||||||
start, end := -1, -1
|
start, end := -1, -1
|
||||||
for i := 0; i < len(a); i += 2 {
|
for i := 0; i < len(a); i += 2 {
|
||||||
|
Reference in New Issue
Block a user