package main import ( "context" "log" gen "slimming/proto/gen" "time" "github.com/songgao/packets/ethernet" "github.com/songgao/water" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" ) type NetCard struct { FrameChan chan [][]byte ifce *water.Interface cli *RPCClient server *RPCServer } type RPCClient struct { FrameChan chan [][]byte conn *grpc.ClientConn } func (cli *RPCClient) connect() { log.Println("rpcclient start") defer log.Println("rpcclient exit") conn, err := grpc.Dial(*othersAddr, grpc.WithTransportCredentials(insecure.NewCredentials()), ) if err != nil { log.Printf("did not connect: %v", err) return } cli.conn = conn go cli.run() } func (cli *RPCClient) run() { c := gen.NewFrameServiceClient(cli.conn) ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) defer cancel() stream, err := c.SendFrames(ctx) if err != nil { panic(err) } for { // Contact the server and print out its response. // 发到对面的网卡 err = stream.Send(&gen.Request{ Frames: <-cli.FrameChan, }) if err != nil { panic(err) } } } func (nc *NetCard) Run() { go nc.runRead() go nc.runWrite() // go nc.cli.run() nc.server.run() } func NewNetCard() *NetCard { config := water.Config{ DeviceType: water.TAP, } config.Name = "stap" ifce, err := water.New(config) if err != nil { log.Fatal(err) } nc := &NetCard{ FrameChan: make(chan [][]byte, 2000), ifce: ifce, cli: &RPCClient{FrameChan: make(chan [][]byte, 2000)}, } nc.server = newRPCServer(nc) return nc } func (nc *NetCard) runRead() { var ifce *water.Interface = nc.ifce var ticker time.Ticker = *time.NewTicker(time.Millisecond * 20) for { var framesBytes [][]byte for range ticker.C { var rframe ethernet.Frame rframe.Resize(1500) n, err := ifce.Read([]byte(rframe)) if err != nil { log.Fatal(err) } rframe = rframe[:n] framesBytes = append(framesBytes, []byte(rframe)) } if len(framesBytes) > 0 { if nc.cli.conn == nil { nc.cli.connect() } if nc.cli.conn != nil { nc.cli.FrameChan <- framesBytes // 网卡数据 发到对方 } } // 写到grpc服务 // log.Printf("Dst: %s\n", rframe.Destination()[0:4]) // log.Printf("Src: %s\n", rframe.Source()[0:4]) // log.Printf("Ethertype: % x\n", rframe.Ethertype()) // log.Printf("Payload: % x\n", rframe.Payload()) } } func (nc *NetCard) runWrite() { var ifce *water.Interface = nc.ifce for wframes := range nc.FrameChan { for _, wframe := range wframes { _, err := ifce.Write(wframe) if err != nil { panic(err) } } } }