Example #1
0
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())
}
Example #2
0
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
}
Example #3
0
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
}
Example #4
0
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)
	}
}
Example #5
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
}
Example #6
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
}