func NewNamedPortManager(datapath Datapath) (*NamedPortManager, error) { self := &NamedPortManager{ datapath: datapath, ports: make(map[uint32]*NamedPort), lock: &sync.Mutex{}, } if ghub, err := nlgo.NewGenlHub(); err != nil { return nil, err } else if hub, err := nlgo.NewRtHub(); err != nil { ghub.Close() return nil, err } else if rhub, err := nlgo.NewRtHub(); err != nil { ghub.Close() hub.Close() return nil, err } else { self.hub = hub self.ghub = ghub self.rhub = rhub if err := hub.Add(syscall.RTNLGRP_LINK, self); err != nil { hub.Close() ghub.Close() return nil, err } } return self, nil }
func (self *Client) init() error { if genlHub, err := nlgo.NewGenlHub(); err != nil { return err } else { self.genlHub = genlHub } // lookup family if genlFamily := self.genlHub.Family(IPVS_GENL_NAME); genlFamily.Id == 0 { return fmt.Errorf("Invalid genl family: %v", IPVS_GENL_NAME) } else if genlFamily.Version != IPVS_GENL_VERSION { return fmt.Errorf("Unsupported ipvs genl family: %+v", genlFamily) } else { self.logDebug.Printf("genlFamily: %+v\n", genlFamily) self.genlFamily = genlFamily } return nil }
func main() { cap := capture{} ghub, e1 := nlgo.NewGenlHub() if e1 != nil { panic(e1) } nl80211 := ghub.Family("nl80211") msgs, e2 := ghub.Sync(nlgo.GenlFamilyCtrl.DumpRequest(nlgo.CTRL_CMD_GETFAMILY)) if e2 != nil { panic(e2) } for _, msg := range msgs { switch msg.Header.Type { case syscall.NLMSG_DONE: // do nothing case syscall.NLMSG_ERROR: log.Print(nlgo.NlMsgerr(msg.NetlinkMessage)) case nlgo.GENL_ID_CTRL: if family, groups, e3 := nlgo.GenlCtrl(nlgo.GenlFamilyCtrl).Parse(msg); e3 != nil { panic(e3) } else if family.Name != "nl80211" { continue } else if msg.Genl().Cmd == nlgo.CTRL_CMD_NEWFAMILY { for _, group := range groups { if e4 := ghub.Add("nl80211", group.Name, cap); e4 != nil { panic(e4) } } } } } if err := ghub.Async(nl80211.DumpRequest(nlgo.NL80211_CMD_GET_WIPHY), cap); err != nil { panic(err) } wait := make(chan bool) <-wait }
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 }