func pack(in interface{}) nlgo.Binary { var buf bytes.Buffer if err := binary.Write(&buf, binary.BigEndian, in); err != nil { panic(err) } return nlgo.Binary(buf.Bytes()) }
func (self NamedPort) get6lowpanMac(addr net.IP) net.HardwareAddr { req := syscall.NetlinkMessage{ Header: syscall.NlMsghdr{ Type: syscall.RTM_GETROUTE, Flags: syscall.NLM_F_REQUEST, }, } (*nlgo.RtMessage)(&req).Set( syscall.RtMsg{ Family: syscall.AF_INET6, }, nlgo.AttrSlice{ nlgo.Attr{ Header: syscall.NlAttr{ Type: syscall.RTA_DST, }, Value: nlgo.Binary(addr.To16()), }, }, ) if msgs, err := self.rhub.Sync(req); err != nil { return nil } else { for _, msg := range msgs { switch msg.Header.Type { case syscall.NLMSG_ERROR: err := nlgo.NlMsgerr(msg) if err.Payload().Error != 0 { log.Print(err) } case syscall.RTM_NEWROUTE: if attr, err := nlgo.RtMessage(msg).Attrs(); err != nil { return nil } else if gw := attr.(nlgo.AttrMap).Get(nlgo.RTA_GATEWAY); gw != nil { if mac := v6toMac(net.IP(gw.(nlgo.Binary))); mac != nil { return mac } } } } } if mac := v6toMac(addr); mac != nil { return mac } return nil }
func (self NamedPort) get6lowpanMac(addr net.IP) net.HardwareAddr { if msgs, err := self.rhub.Request( syscall.RTM_GETROUTE, syscall.NLM_F_REQUEST, (*[syscall.SizeofRtMsg]byte)(unsafe.Pointer(&syscall.RtMsg{ Family: syscall.AF_INET6, }))[:], nlgo.AttrSlice{ nlgo.Attr{ Header: syscall.NlAttr{ Type: syscall.RTA_DST, }, Value: nlgo.Binary(addr.To16()), }, }, ); err != nil { return nil } else { for _, msg := range msgs { if msg.Error != nil { continue } switch msg.Message.Header.Type { case syscall.RTM_NEWROUTE: if attr, err := nlgo.RoutePolicy.Parse(msg.Message.Data[nlgo.NLMSG_ALIGN(syscall.SizeofRtMsg):]); err != nil { return nil } else if gw := attr.(nlgo.AttrMap).Get(nlgo.RTA_GATEWAY); gw != nil { if mac := v6toMac(net.IP(gw.(nlgo.Binary))); mac != nil { return mac } } } } } if mac := v6toMac(addr); mac != nil { return mac } return nil }
func TestDest(t *testing.T) { testService := Service{ Af: syscall.AF_INET6, } testDest := Dest{ Addr: net.ParseIP("2001:db8:6b:6b::0"), Port: 1337, FwdMethod: IP_VS_CONN_F_TUNNEL, Weight: 10, UThresh: 1000, LThresh: 0, } testAttrs := nlgo.AttrSlice{ nlattr(IPVS_DEST_ATTR_ADDR, nlgo.Binary([]byte{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x6b, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), nlattr(IPVS_DEST_ATTR_PORT, nlgo.U16(0x3905)), nlattr(IPVS_DEST_ATTR_FWD_METHOD, nlgo.U32(IP_VS_CONN_F_TUNNEL)), nlattr(IPVS_DEST_ATTR_WEIGHT, nlgo.U32(10)), nlattr(IPVS_DEST_ATTR_U_THRESH, nlgo.U32(1000)), nlattr(IPVS_DEST_ATTR_L_THRESH, nlgo.U32(0)), } // pack packAttrs := testDest.attrs(&testService, true) packBytes := packAttrs.Bytes() if !bytes.Equal(packBytes, testAttrs.Bytes()) { t.Errorf("fail Dest.attrs(): \n%s", hex.Dump(packBytes)) } // unpack if unpackedAttrs, err := ipvs_dest_policy.Parse(packBytes); err != nil { t.Fatalf("error ipvs_dest_policy.Parse: %s", err) } else if unpackedDest, err := unpackDest(testService, unpackedAttrs.(nlgo.AttrMap)); err != nil { t.Fatalf("error unpackDest: %s", err) } else { testDestEquals(t, testDest, unpackedDest) } }
func (self NamedPort) Egress(pkt Frame) error { if self.fd == -1 { return fmt.Errorf("port closed") } switch self.hatype { case syscall.ARPHRD_ETHER: dot11 := false for _, oob := range fetchOxmExperimenter(pkt.Oob) { if oob.Experimenter == oxm.STRATOS_EXPERIMENTER_ID && oob.Field == oxm.STRATOS_OXM_FIELD_BASIC && oob.Type == oxm.STROXM_BASIC_DOT11 && oob.Value[0] == 1 { dot11 = true } } if dot11 && self.wiphy != 0 { if self.ghub == nil { if hub, err := nlgo.NewGenlHub(); err != nil { return err } else { self.ghub = hub } } self.ghub.Add("nl80211", "mlme", self) status := make(chan error) defer close(status) if err := func() error { if buf, err := pkt.Dot11(); err != nil { return err } else { self.lock.Lock() defer self.lock.Unlock() if res, err := self.ghub.Request("nl80211", 1, nlgo.NL80211_CMD_FRAME, 0, nil, nlgo.AttrSlice{ nlgo.Attr{ Header: syscall.NlAttr{ Type: nlgo.NL80211_ATTR_FRAME, }, Value: nlgo.Binary(buf), }, }); err != nil { return err } else { for _, r := range res { if len(r.Family) == 0 { return fmt.Errorf("NL80211_CMD_FRAME failed") } else if r.Family == "nl80211" { if attrs, err := nlgo.Nl80211Policy.Parse(r.Payload); err != nil { return err } else { cookie := uint64(attrs.(nlgo.AttrMap).Get(nlgo.NL80211_ATTR_COOKIE).(nlgo.U64)) self.txStatus[cookie] = status } } } } } return nil }(); err != nil { return err } if err := <-status; err != nil { return err } } else { buf := pkt.Data if n, err := syscall.Write(self.fd, buf); err != nil { return err } else if n != len(buf) { return fmt.Errorf("write not complete") } } case syscall.ARPHRD_IEEE80211_RADIOTAP: // XXX: only when Dot11 flag ? if buf, err := pkt.Radiotap(); err != nil { return err } else if n, err := syscall.Write(self.fd, buf); err != nil { return err } else if n != len(buf) { return fmt.Errorf("write not complete") } case syscall2.ARPHRD_6LOWPAN: if binary.BigEndian.Uint16(pkt.Data[12:]) == 0x86DD { buf := pkt.Data[14:] if n, err := syscall.Write(self.fd, buf); err != nil { return err } else if n != len(buf) { return fmt.Errorf("write not complete") } } } return nil }
func (self *NamedPort) Vendor(reqAny interface{}) interface{} { mgmtFramesSync := func() error { if len(self.mgmtFrames) == 0 { return nil } if self.ghub != nil { self.ghub.Close() self.ghub = nil } if self.ghub == nil { if hub, err := nlgo.NewGenlHub(); err != nil { return err } else { self.ghub = hub } } for _, fr := range self.mgmtFrames { if hres, err := self.ghub.Request("nl80211", 1, nlgo.NL80211_CMD_REGISTER_FRAME, 0, nil, nlgo.AttrSlice{ nlgo.Attr{ Header: syscall.NlAttr{ Type: nlgo.NL80211_ATTR_FRAME_MATCH, }, Value: nlgo.Binary(fr), }, }); err != nil { return err } else { for _, hr := range hres { if hr.Header.Type == syscall.NLMSG_ERROR { return fmt.Errorf("NL80211_CMD_REGISTER_FRAME failed") } } } } return nil } switch req := reqAny.(type) { case MgmtFrameAdd: prefix := MgmtFramePrefix(req) for _, p := range self.mgmtFrames { if bytes.Equal([]byte(p), []byte(prefix)) { return nil } } self.mgmtFrames = append(self.mgmtFrames, prefix) if err := mgmtFramesSync(); err != nil { return err } case MgmtFrameRemove: prefix := MgmtFramePrefix(req) var newMgmtFrames []MgmtFramePrefix for _, p := range self.mgmtFrames { if !bytes.Equal([]byte(p), []byte(prefix)) { newMgmtFrames = append(newMgmtFrames, p) } } self.mgmtFrames = newMgmtFrames if err := mgmtFramesSync(); err != nil { return err } } return nil }