mirror of
https://github.com/impact-eintr/netstack.git
synced 2025-10-06 05:16:50 +08:00
NIC 对象绑定IP还未实现完成 明天继续
This commit is contained in:
@@ -1,11 +1,32 @@
|
||||
package stack
|
||||
|
||||
import (
|
||||
"log"
|
||||
"netstack/ilist"
|
||||
"netstack/tcpip"
|
||||
"netstack/tcpip/buffer"
|
||||
"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来代表它在我们自己的协议栈中的网卡对象
|
||||
type NIC struct {
|
||||
stack *Stack
|
||||
@@ -24,7 +45,57 @@ type NIC struct {
|
||||
promiscuous bool // 混杂模式
|
||||
primary map[tcpip.NetworkProtocolNumber]*ilist.List
|
||||
// 网络层端的记录
|
||||
endpoints map[NetworkEndpoingID]*referencedNetworkEndpoint
|
||||
endpoints map[NetworkEndpointID]*referencedNetworkEndpoint
|
||||
// 子网的记录
|
||||
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
|
||||
|
||||
import (
|
||||
"log"
|
||||
"netstack/ilist"
|
||||
"netstack/sleep"
|
||||
"netstack/tcpip"
|
||||
@@ -89,9 +90,16 @@ type NetworkDispatcher interface {
|
||||
|
||||
type LinkEndpointCapabilities uint
|
||||
|
||||
// type TransportProtocolFactory func() TransportProtocol TODO
|
||||
|
||||
type NetworkProtocolFactory func() NetworkProtocol
|
||||
|
||||
var (
|
||||
// 以下两个map需要在init函数中注册
|
||||
// 传输层协议的注册存储结构 TODO
|
||||
// 网络层协议的注册存储结构 TODO
|
||||
//transportProtocols = make(map[string]TransportProtocolFactory)
|
||||
// 网络层协议的注册存储结构
|
||||
networkProtocols = make(map[string]NetworkProtocolFactory)
|
||||
|
||||
linkEPMu sync.RWMutex
|
||||
nextLinkEndpointID tcpip.LinkEndpointID = 1
|
||||
@@ -100,7 +108,8 @@ var (
|
||||
|
||||
// ==============================网络层相关==============================
|
||||
type NetworkProtocol interface {
|
||||
// TODO 需要添加
|
||||
Number() tcpip.NetworkProtocolNumber
|
||||
// todo 需要添加
|
||||
}
|
||||
|
||||
// NetworkEndpoint是需要由网络层协议(例如,ipv4,ipv6)的端点实现的接口
|
||||
@@ -108,7 +117,7 @@ type NetworkEndpoint interface {
|
||||
// TODO 需要添加
|
||||
}
|
||||
|
||||
type NetworkEndpoingID struct {
|
||||
type NetworkEndpointID struct {
|
||||
LocalAddress tcpip.Address
|
||||
}
|
||||
|
||||
@@ -147,6 +156,12 @@ type referencedNetworkEndpoint struct {
|
||||
holdsInsertRef bool
|
||||
}
|
||||
|
||||
// 注册一个新的网络协议工厂
|
||||
func RegisterNetworkProtocolFactory(name string, p NetworkProtocolFactory) {
|
||||
networkProtocols[name] = p
|
||||
log.Println(networkProtocols)
|
||||
}
|
||||
|
||||
// 注册一个链路层设备
|
||||
func RegisterLinkEndpoint(linkEP LinkEndpoint) tcpip.LinkEndpointID {
|
||||
linkEPMu.Lock()
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package stack
|
||||
|
||||
import (
|
||||
"log"
|
||||
"netstack/tcpip"
|
||||
"netstack/tcpip/ports"
|
||||
"sync"
|
||||
@@ -48,6 +49,31 @@ type Stack struct {
|
||||
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 {
|
||||
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 {
|
||||
return tcpip.ErrDuplicateNICID
|
||||
}
|
||||
n := newIC(s, id, name, ep)
|
||||
n := newNIC(s, id, name, ep)
|
||||
|
||||
s.nics[id] = n
|
||||
if enable {
|
||||
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
|
||||
|
||||
import (
|
||||
"log"
|
||||
"netstack/tcpip"
|
||||
"netstack/tcpip/buffer"
|
||||
"netstack/tcpip/link/channel"
|
||||
"netstack/tcpip/stack"
|
||||
"testing"
|
||||
@@ -10,12 +13,33 @@ const (
|
||||
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) {
|
||||
|
||||
myStack := &stack.Stack{}
|
||||
id, _ := channel.New(10, defaultMTU, "")
|
||||
myStack := stack.New([]string{"fakeNet"})
|
||||
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)
|
||||
}
|
||||
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 {
|
||||
fmt.Println(string(a), len(a))
|
||||
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 {
|
||||
|
Reference in New Issue
Block a user