Пример #1
0
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
}
Пример #2
0
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
}
Пример #3
0
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
}
Пример #4
0
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
}
Пример #5
0
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
}