func (self capture) GenlListen(msg nlgo.GenlMessage) { switch msg.Header.Type { case syscall.NLMSG_DONE: log.Print("Init DONE") case syscall.NLMSG_ERROR: log.Print(nlgo.NlMsgerr(msg.NetlinkMessage)) default: if attrs, err := nlgo.Nl80211Policy.Parse(msg.Body()); err != nil { panic(err) } else { log.Printf("NL80211_CMD_%s attrs=%s", nlgo.NL80211_CMD_itoa[msg.Genl().Cmd], attrs) } } }
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 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 }
// Execute a command with return messages (via handler) , returning error func (self *Client) request(request Request, responsePolicy nlgo.MapPolicy, responseHandler func(attrs nlgo.AttrMap) error) error { self.logDebug.Printf("Client.request: cmd=%02x flags=%04x attrs=%v", request.Cmd, request.Flags, request.Attrs) msg := self.genlFamily.Request(request.Cmd, request.Flags, nil, request.Attrs.Bytes()) if out, err := self.genlHub.Sync(msg); err != nil { return err } else { for _, msg := range out { if msg.Header.Type == syscall.NLMSG_ERROR { if msgErr := nlgo.NlMsgerr(msg.NetlinkMessage); msgErr.Payload().Error != 0 { return msgErr } else { // ack } } else if msg.Header.Type == syscall.NLMSG_DONE { self.logDebug.Printf("Client.request: done") } else if msg.Family == self.genlFamily { if attrsValue, err := responsePolicy.Parse(msg.Body()); err != nil { return fmt.Errorf("ipvs:Client.request: Invalid response: %s\n%s", err, hex.Dump(msg.Data)) } else if attrMap, ok := attrsValue.(nlgo.AttrMap); !ok { return fmt.Errorf("ipvs:Client.request: Invalid attrs value: %v", attrsValue) } else { self.logDebug.Printf("Client.request: \t%v\n", attrMap) if err := responseHandler(attrMap); err != nil { return err } } } else { self.logWarning.Printf("Client.request: Unknown response: %+v", msg) } } } return nil }
// Execute a command with success/error, no return messages func (self *Client) exec(request Request) error { self.logDebug.Printf("Client.exec: cmd=%02x flags=%04x...", request.Cmd, request.Flags) msg := self.genlFamily.Request(request.Cmd, request.Flags, nil, request.Attrs.Bytes()) if out, err := self.genlHub.Sync(msg); err != nil { return err } else { for _, msg := range out { if msg.Header.Type == syscall.NLMSG_ERROR { if msgErr := nlgo.NlMsgerr(msg.NetlinkMessage); msgErr.Payload().Error != 0 { return msgErr } else { // ack } } else { self.logWarning.Printf("Client.exec: Unexpected response: %+v", msg) } } return nil } }
func GetTaskStats(nlsk *nlgo.NlSock, p int) (t *Taskstats) { nlsk.Flags |= nlgo.NL_NO_AUTO_ACK const familyID = 22 m := &MSG{ Len: 8, Type: TASKSTATS_CMD_ATTR_PID, Pid: uint32(p), } hdr := (*[nlgo.SizeofGenlMsghdr]byte)(unsafe.Pointer(&nlgo.GenlMsghdr{ Cmd: TASKSTATS_CMD_GET, Version: 0, }))[:] req := ((*[8]byte)(unsafe.Pointer(m)))[:] length := 4 pad := ((length + 4 - 1) & (^3)) - length for i := 0; i < pad; i++ { req = append(req, 0) } hdr = append(hdr, req...) nlgo.NlSendSimple(nlsk, familyID, 1, hdr[:]) func() error { for { buf := make([]byte, 16384) if nn, _, err := syscall.Recvfrom(nlsk.Fd, buf, 0); err != nil { return err } else if nn > len(buf) { return nlgo.NLE_MSG_TRUNC } else { buf = buf[:nn] } if msgs, err := syscall.ParseNetlinkMessage(buf); err != nil { return err } else { for _, msg := range msgs { switch msg.Header.Type { case syscall.NLMSG_DONE: return nil case syscall.NLMSG_ERROR: return fmt.Errorf("NlMsgerr=%s", nlgo.NlMsgerr(msg)) case 22: genl := (*nlgo.GenlMsghdr)(unsafe.Pointer(&msg.Data[0])) _ = genl attrs := parse_attributes(msg.Data[nlgo.GENL_HDRLEN:]) for _, attr := range attrs { if attr.Type == TASKSTATS_TYPE_AGGR_PID { attrs = parse_attributes(attr.Data) break } } for _, attr := range attrs { if attr.Type == TASKSTATS_TYPE_STATS { _ = uint32(*(*uint32)(unsafe.Pointer(&attr.Data[248]))) t = (*Taskstats)(unsafe.Pointer(&attr.Data[0])) break } } return nil default: return fmt.Errorf("unexpected NlMsghdr=%s", msg.Header) } } } } }() // if err != nil { // fmt.Println(err, err.Error()) // } return }