From 103b22a060983660631afc8cfc2441179ff9229f Mon Sep 17 00:00:00 2001 From: mame82 Date: Wed, 9 May 2018 15:22:07 +0000 Subject: [PATCH] Incorporated and modified netlink, due to missing functionality --- netlink/netlink.go | 31 + netlink/netlink_linux.go | 1655 +++++++++++++++++++++++++++++ netlink/netlink_linux_armppc64.go | 7 + netlink/netlink_linux_notarm.go | 7 + netlink/netlink_linux_test.go | 408 +++++++ proto/grpc.pb.go | 209 ++-- proto/grpc.proto | 8 +- service/DHCPSrv.go | 44 - service/defaults.go | 73 ++ service/network.go | 18 +- service/usb.go | 38 +- 11 files changed, 2324 insertions(+), 174 deletions(-) create mode 100644 netlink/netlink.go create mode 100644 netlink/netlink_linux.go create mode 100644 netlink/netlink_linux_armppc64.go create mode 100644 netlink/netlink_linux_notarm.go create mode 100644 netlink/netlink_linux_test.go create mode 100644 service/defaults.go diff --git a/netlink/netlink.go b/netlink/netlink.go new file mode 100644 index 0000000..9088366 --- /dev/null +++ b/netlink/netlink.go @@ -0,0 +1,31 @@ +// Packet netlink provide access to low level Netlink sockets and messages. +// +// Actual implementations are in: +// netlink_linux.go +// netlink_darwin.go +package netlink + +import ( + "errors" + "net" +) + +var ( + ErrWrongSockType = errors.New("Wrong socket type") + ErrShortResponse = errors.New("Got short response from netlink") + ErrInterfaceExists = errors.New("Network interface already exists") +) + +// A Route is a subnet associated with the interface to reach it. +type Route struct { + *net.IPNet + Iface *net.Interface + Default bool +} + +// An IfAddr defines IP network settings for a given network interface +type IfAddr struct { + Iface *net.Interface + IP net.IP + IPNet *net.IPNet +} diff --git a/netlink/netlink_linux.go b/netlink/netlink_linux.go new file mode 100644 index 0000000..2773e34 --- /dev/null +++ b/netlink/netlink_linux.go @@ -0,0 +1,1655 @@ +package netlink + +import ( + "encoding/binary" + "fmt" + "io" + "math/rand" + "net" + "os" + "sync/atomic" + "syscall" + "time" + "unsafe" + "errors" +) + +const ( + IFNAMSIZ = 16 + DEFAULT_CHANGE = 0xFFFFFFFF + IFLA_INFO_KIND = 1 + IFLA_INFO_DATA = 2 + VETH_INFO_PEER = 1 + IFLA_MACVLAN_MODE = 1 + IFLA_VLAN_ID = 1 + IFLA_NET_NS_FD = 28 + IFLA_ADDRESS = 1 + IFLA_BRPORT_MODE = 4 + SIOC_BRADDBR = 0x89a0 + SIOC_BRDELBR = 0x89a1 + SIOC_BRADDIF = 0x89a2 + SIOC_BRDELIF = 0x89a3 +) + +const ( + MACVLAN_MODE_PRIVATE = 1 << iota + MACVLAN_MODE_VEPA + MACVLAN_MODE_BRIDGE + MACVLAN_MODE_PASSTHRU +) + + +const ( + // See linux/if_arp.h. + // Note that Linux doesn't support IPv4 over IPv6 tunneling. + sysARPHardwareIPv4IPv4 = 768 // IPv4 over IPv4 tunneling + sysARPHardwareIPv6IPv6 = 769 // IPv6 over IPv6 tunneling + sysARPHardwareIPv6IPv4 = 776 // IPv6 over IPv4 tunneling + sysARPHardwareGREIPv4 = 778 // any over GRE over IPv4 tunneling + sysARPHardwareGREIPv6 = 823 // any over GRE over IPv6 tunneling +) + +var errNoSuchInterface = errors.New("no such network interface") + +var nextSeqNr uint32 + +type ifreqHwaddr struct { + IfrnName [IFNAMSIZ]byte + IfruHwaddr syscall.RawSockaddr +} + +type ifreqIndex struct { + IfrnName [IFNAMSIZ]byte + IfruIndex int32 +} + +type ifreqFlags struct { + IfrnName [IFNAMSIZ]byte + Ifruflags uint16 +} + +var native binary.ByteOrder + +var rnd = rand.New(rand.NewSource(time.Now().UnixNano())) + +func init() { + var x uint32 = 0x01020304 + if *(*byte)(unsafe.Pointer(&x)) == 0x01 { + native = binary.BigEndian + } else { + native = binary.LittleEndian + } +} + +func getIpFamily(ip net.IP) int { + if len(ip) <= net.IPv4len { + return syscall.AF_INET + } + if ip.To4() != nil { + return syscall.AF_INET + } + return syscall.AF_INET6 +} + +type NetlinkRequestData interface { + Len() int + ToWireFormat() []byte +} + +type IfInfomsg struct { + syscall.IfInfomsg +} + +func newIfInfomsg(family int) *IfInfomsg { + return &IfInfomsg{ + IfInfomsg: syscall.IfInfomsg{ + Family: uint8(family), + }, + } +} + +func newIfInfomsgChild(parent *RtAttr, family int) *IfInfomsg { + msg := newIfInfomsg(family) + parent.children = append(parent.children, msg) + return msg +} + +func (msg *IfInfomsg) ToWireFormat() []byte { + length := syscall.SizeofIfInfomsg + b := make([]byte, length) + b[0] = msg.Family + b[1] = 0 + native.PutUint16(b[2:4], msg.Type) + native.PutUint32(b[4:8], uint32(msg.Index)) + native.PutUint32(b[8:12], msg.Flags) + native.PutUint32(b[12:16], msg.Change) + return b +} + +func (msg *IfInfomsg) Len() int { + return syscall.SizeofIfInfomsg +} + +type IfAddrmsg struct { + syscall.IfAddrmsg +} + +func newIfAddrmsg(family int) *IfAddrmsg { + return &IfAddrmsg{ + IfAddrmsg: syscall.IfAddrmsg{ + Family: uint8(family), + }, + } +} + +func (msg *IfAddrmsg) ToWireFormat() []byte { + length := syscall.SizeofIfAddrmsg + b := make([]byte, length) + b[0] = msg.Family + b[1] = msg.Prefixlen + b[2] = msg.Flags + b[3] = msg.Scope + native.PutUint32(b[4:8], msg.Index) + return b +} + +func (msg *IfAddrmsg) Len() int { + return syscall.SizeofIfAddrmsg +} + +type RtGenmsg struct { + syscall.RtGenmsg +} + +func newRtGenMsg(family int) *RtGenmsg { + return &RtGenmsg{ + RtGenmsg: syscall.RtGenmsg{ + Family: uint8(family), + }, + } +} + +func (msg *RtGenmsg) ToWireFormat() []byte { + length := syscall.SizeofRtGenmsg + b := make([]byte, length) + b[0] = msg.Family + return b +} + +func (msg *RtGenmsg) Len() int { + return syscall.SizeofRtGenmsg +} + +type RtMsg struct { + syscall.RtMsg +} + +func newRtMsg() *RtMsg { + return &RtMsg{ + RtMsg: syscall.RtMsg{ + Table: syscall.RT_TABLE_MAIN, + Scope: syscall.RT_SCOPE_UNIVERSE, + Protocol: syscall.RTPROT_BOOT, + Type: syscall.RTN_UNICAST, + }, + } +} + +func (msg *RtMsg) ToWireFormat() []byte { + length := syscall.SizeofRtMsg + b := make([]byte, length) + b[0] = msg.Family + b[1] = msg.Dst_len + b[2] = msg.Src_len + b[3] = msg.Tos + b[4] = msg.Table + b[5] = msg.Protocol + b[6] = msg.Scope + b[7] = msg.Type + native.PutUint32(b[8:12], msg.Flags) + return b +} + +func (msg *RtMsg) Len() int { + return syscall.SizeofRtMsg +} + +func rtaAlignOf(attrlen int) int { + return (attrlen + syscall.RTA_ALIGNTO - 1) & ^(syscall.RTA_ALIGNTO - 1) +} + +type RtAttr struct { + syscall.RtAttr + Data []byte + children []NetlinkRequestData +} + +func newRtAttr(attrType int, data []byte) *RtAttr { + return &RtAttr{ + RtAttr: syscall.RtAttr{ + Type: uint16(attrType), + }, + children: []NetlinkRequestData{}, + Data: data, + } +} + +func newRtAttrChild(parent *RtAttr, attrType int, data []byte) *RtAttr { + attr := newRtAttr(attrType, data) + parent.children = append(parent.children, attr) + return attr +} + +func (a *RtAttr) Len() int { + if len(a.children) == 0 { + return (syscall.SizeofRtAttr + len(a.Data)) + } + + l := 0 + for _, child := range a.children { + l += child.Len() + } + l += syscall.SizeofRtAttr + return rtaAlignOf(l + len(a.Data)) +} + +func (a *RtAttr) ToWireFormat() []byte { + length := a.Len() + buf := make([]byte, rtaAlignOf(length)) + + if a.Data != nil { + copy(buf[4:], a.Data) + } else { + next := 4 + for _, child := range a.children { + childBuf := child.ToWireFormat() + copy(buf[next:], childBuf) + next += rtaAlignOf(len(childBuf)) + } + } + + if l := uint16(length); l != 0 { + native.PutUint16(buf[0:2], l) + } + native.PutUint16(buf[2:4], a.Type) + return buf +} + +func uint32Attr(t int, n uint32) *RtAttr { + buf := make([]byte, 4) + native.PutUint32(buf, n) + return newRtAttr(t, buf) +} + +type NetlinkRequest struct { + syscall.NlMsghdr + Data []NetlinkRequestData +} + +func (rr *NetlinkRequest) ToWireFormat() []byte { + length := rr.Len + dataBytes := make([][]byte, len(rr.Data)) + for i, data := range rr.Data { + dataBytes[i] = data.ToWireFormat() + length += uint32(len(dataBytes[i])) + } + b := make([]byte, length) + native.PutUint32(b[0:4], length) + native.PutUint16(b[4:6], rr.Type) + native.PutUint16(b[6:8], rr.Flags) + native.PutUint32(b[8:12], rr.Seq) + native.PutUint32(b[12:16], rr.Pid) + + next := 16 + for _, data := range dataBytes { + copy(b[next:], data) + next += len(data) + } + return b +} + +func (rr *NetlinkRequest) AddData(data NetlinkRequestData) { + if data != nil { + rr.Data = append(rr.Data, data) + } +} + +func newNetlinkRequest(proto, flags int) *NetlinkRequest { + return &NetlinkRequest{ + NlMsghdr: syscall.NlMsghdr{ + Len: uint32(syscall.NLMSG_HDRLEN), + Type: uint16(proto), + Flags: syscall.NLM_F_REQUEST | uint16(flags), + Seq: atomic.AddUint32(&nextSeqNr, 1), + }, + } +} + +type NetlinkSocket struct { + fd int + lsa syscall.SockaddrNetlink +} + +func getNetlinkSocket() (*NetlinkSocket, error) { + fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_ROUTE) + if err != nil { + return nil, err + } + s := &NetlinkSocket{ + fd: fd, + } + s.lsa.Family = syscall.AF_NETLINK + if err := syscall.Bind(fd, &s.lsa); err != nil { + syscall.Close(fd) + return nil, err + } + + return s, nil +} + +func (s *NetlinkSocket) Close() { + syscall.Close(s.fd) +} + +func (s *NetlinkSocket) Send(request *NetlinkRequest) error { + if err := syscall.Sendto(s.fd, request.ToWireFormat(), 0, &s.lsa); err != nil { + return err + } + return nil +} + +func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, error) { + rb := make([]byte, syscall.Getpagesize()) + nr, _, err := syscall.Recvfrom(s.fd, rb, 0) + if err != nil { + return nil, err + } + if nr < syscall.NLMSG_HDRLEN { + return nil, ErrShortResponse + } + rb = rb[:nr] + return syscall.ParseNetlinkMessage(rb) +} + +func (s *NetlinkSocket) GetPid() (uint32, error) { + lsa, err := syscall.Getsockname(s.fd) + if err != nil { + return 0, err + } + switch v := lsa.(type) { + case *syscall.SockaddrNetlink: + return v.Pid, nil + } + return 0, ErrWrongSockType +} + +func (s *NetlinkSocket) CheckMessage(m syscall.NetlinkMessage, seq, pid uint32) error { + if m.Header.Seq != seq { + return fmt.Errorf("netlink: invalid seq %d, expected %d", m.Header.Seq, seq) + } + if m.Header.Pid != pid { + return fmt.Errorf("netlink: wrong pid %d, expected %d", m.Header.Pid, pid) + } + if m.Header.Type == syscall.NLMSG_DONE { + return io.EOF + } + if m.Header.Type == syscall.NLMSG_ERROR { + e := int32(native.Uint32(m.Data[0:4])) + if e == 0 { + return io.EOF + } + return syscall.Errno(-e) + } + return nil +} + +func (s *NetlinkSocket) HandleAck(seq uint32) error { + pid, err := s.GetPid() + if err != nil { + return err + } + +outer: + for { + msgs, err := s.Receive() + if err != nil { + return err + } + for _, m := range msgs { + if err := s.CheckMessage(m, seq, pid); err != nil { + if err == io.EOF { + break outer + } + return err + } + } + } + + return nil +} + +func zeroTerminated(s string) []byte { + return []byte(s + "\000") +} + +func nonZeroTerminated(s string) []byte { + return []byte(s) +} + +// Add a new network link of a specified type. +// This is identical to running: ip link add $name type $linkType +func NetworkLinkAdd(name string, linkType string) error { + if name == "" || linkType == "" { + return fmt.Errorf("Neither link name nor link type can be empty!") + } + + s, err := getNetlinkSocket() + if err != nil { + return err + } + defer s.Close() + + wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) + + msg := newIfInfomsg(syscall.AF_UNSPEC) + wb.AddData(msg) + + linkInfo := newRtAttr(syscall.IFLA_LINKINFO, nil) + newRtAttrChild(linkInfo, IFLA_INFO_KIND, nonZeroTerminated(linkType)) + wb.AddData(linkInfo) + + nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(name)) + wb.AddData(nameData) + + if err := s.Send(wb); err != nil { + return err + } + + return s.HandleAck(wb.Seq) +} + +// Delete a network link. +// This is identical to running: ip link del $name +func NetworkLinkDel(name string) error { + if name == "" { + return fmt.Errorf("Network link name can not be empty!") + } + + s, err := getNetlinkSocket() + if err != nil { + return err + } + defer s.Close() + + iface, err := net.InterfaceByName(name) + if err != nil { + return err + } + + wb := newNetlinkRequest(syscall.RTM_DELLINK, syscall.NLM_F_ACK) + + msg := newIfInfomsg(syscall.AF_UNSPEC) + msg.Index = int32(iface.Index) + wb.AddData(msg) + + if err := s.Send(wb); err != nil { + return err + } + + return s.HandleAck(wb.Seq) +} + +// Bring up a particular network interface. +// This is identical to running: ip link set dev $name up +func NetworkLinkUp(iface *net.Interface) error { + s, err := getNetlinkSocket() + if err != nil { + return err + } + defer s.Close() + + wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_ACK) + + msg := newIfInfomsg(syscall.AF_UNSPEC) + msg.Index = int32(iface.Index) + msg.Flags = syscall.IFF_UP + msg.Change = syscall.IFF_UP + wb.AddData(msg) + + if err := s.Send(wb); err != nil { + return err + } + + return s.HandleAck(wb.Seq) +} + +// Bring down a particular network interface. +// This is identical to running: ip link set $name down +func NetworkLinkDown(iface *net.Interface) error { + s, err := getNetlinkSocket() + if err != nil { + return err + } + defer s.Close() + + wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_ACK) + + msg := newIfInfomsg(syscall.AF_UNSPEC) + msg.Index = int32(iface.Index) + msg.Flags = 0 & ^syscall.IFF_UP + msg.Change = DEFAULT_CHANGE + wb.AddData(msg) + + if err := s.Send(wb); err != nil { + return err + } + + return s.HandleAck(wb.Seq) +} + +// Set link layer address ie. MAC Address. +// This is identical to running: ip link set dev $name address $macaddress +func NetworkSetMacAddress(iface *net.Interface, macaddr string) error { + s, err := getNetlinkSocket() + if err != nil { + return err + } + defer s.Close() + + hwaddr, err := net.ParseMAC(macaddr) + if err != nil { + return err + } + + var ( + MULTICAST byte = 0x1 + ) + + if hwaddr[0]&0x1 == MULTICAST { + return fmt.Errorf("Multicast MAC Address is not supported: %s", macaddr) + } + + wb := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) + + msg := newIfInfomsg(syscall.AF_UNSPEC) + msg.Index = int32(iface.Index) + msg.Change = DEFAULT_CHANGE + wb.AddData(msg) + + macdata := make([]byte, 6) + copy(macdata, hwaddr) + data := newRtAttr(IFLA_ADDRESS, macdata) + wb.AddData(data) + + if err := s.Send(wb); err != nil { + return err + } + return s.HandleAck(wb.Seq) +} + +// Set link Maximum Transmission Unit +// This is identical to running: ip link set dev $name mtu $MTU +// bridge is a bitch here https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=292088 +// https://bugzilla.redhat.com/show_bug.cgi?id=697021 +// There is a discussion about how to deal with ifcs joining bridge with MTU > 1500 +// Regular network nterfaces do seem to work though! +func NetworkSetMTU(iface *net.Interface, mtu int) error { + s, err := getNetlinkSocket() + if err != nil { + return err + } + defer s.Close() + + wb := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) + + msg := newIfInfomsg(syscall.AF_UNSPEC) + msg.Type = syscall.RTM_SETLINK + msg.Flags = syscall.NLM_F_REQUEST + msg.Index = int32(iface.Index) + msg.Change = DEFAULT_CHANGE + wb.AddData(msg) + wb.AddData(uint32Attr(syscall.IFLA_MTU, uint32(mtu))) + + if err := s.Send(wb); err != nil { + return err + } + return s.HandleAck(wb.Seq) +} + +// Set link queue length +// This is identical to running: ip link set dev $name txqueuelen $QLEN +func NetworkSetTxQueueLen(iface *net.Interface, txQueueLen int) error { + s, err := getNetlinkSocket() + if err != nil { + return err + } + defer s.Close() + + wb := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) + + msg := newIfInfomsg(syscall.AF_UNSPEC) + msg.Type = syscall.RTM_SETLINK + msg.Flags = syscall.NLM_F_REQUEST + msg.Index = int32(iface.Index) + msg.Change = DEFAULT_CHANGE + wb.AddData(msg) + wb.AddData(uint32Attr(syscall.IFLA_TXQLEN, uint32(txQueueLen))) + + if err := s.Send(wb); err != nil { + return err + } + return s.HandleAck(wb.Seq) +} + +func networkMasterAction(iface *net.Interface, rtattr *RtAttr) error { + s, err := getNetlinkSocket() + if err != nil { + return err + } + defer s.Close() + + wb := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) + + msg := newIfInfomsg(syscall.AF_UNSPEC) + msg.Type = syscall.RTM_SETLINK + msg.Flags = syscall.NLM_F_REQUEST + msg.Index = int32(iface.Index) + msg.Change = DEFAULT_CHANGE + wb.AddData(msg) + wb.AddData(rtattr) + + if err := s.Send(wb); err != nil { + return err + } + + return s.HandleAck(wb.Seq) +} + +// Add an interface to bridge. +// This is identical to running: ip link set $name master $master +func NetworkSetMaster(iface, master *net.Interface) error { + data := uint32Attr(syscall.IFLA_MASTER, uint32(master.Index)) + return networkMasterAction(iface, data) +} + +// Remove an interface from the bridge +// This is is identical to to running: ip link $name set nomaster +func NetworkSetNoMaster(iface *net.Interface) error { + data := uint32Attr(syscall.IFLA_MASTER, 0) + return networkMasterAction(iface, data) +} + +func networkSetNsAction(iface *net.Interface, rtattr *RtAttr) error { + s, err := getNetlinkSocket() + if err != nil { + return err + } + defer s.Close() + + wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_ACK) + msg := newIfInfomsg(syscall.AF_UNSPEC) + msg.Index = int32(iface.Index) + wb.AddData(msg) + wb.AddData(rtattr) + + if err := s.Send(wb); err != nil { + return err + } + + return s.HandleAck(wb.Seq) +} + +// Move a particular network interface to a particular network namespace +// specified by PID. This is identical to running: ip link set dev $name netns $pid +func NetworkSetNsPid(iface *net.Interface, nspid int) error { + data := uint32Attr(syscall.IFLA_NET_NS_PID, uint32(nspid)) + return networkSetNsAction(iface, data) +} + +// Move a particular network interface to a particular mounted +// network namespace specified by file descriptor. +// This is idential to running: ip link set dev $name netns $fd +func NetworkSetNsFd(iface *net.Interface, fd int) error { + data := uint32Attr(IFLA_NET_NS_FD, uint32(fd)) + return networkSetNsAction(iface, data) +} + +// Rename a particular interface to a different name +// !!! Note that you can't rename an active interface. You need to bring it down before renaming it. +// This is identical to running: ip link set dev ${oldName} name ${newName} +func NetworkChangeName(iface *net.Interface, newName string) error { + if len(newName) >= IFNAMSIZ { + return fmt.Errorf("Interface name %s too long", newName) + } + + s, err := getNetlinkSocket() + if err != nil { + return err + } + defer s.Close() + + wb := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) + + msg := newIfInfomsg(syscall.AF_UNSPEC) + msg.Index = int32(iface.Index) + msg.Change = DEFAULT_CHANGE + wb.AddData(msg) + + nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(newName)) + wb.AddData(nameData) + + if err := s.Send(wb); err != nil { + return err + } + + return s.HandleAck(wb.Seq) +} + +// Add a new VETH pair link on the host +// This is identical to running: ip link add name $name type veth peer name $peername +func NetworkCreateVethPair(name1, name2 string, txQueueLen int) error { + s, err := getNetlinkSocket() + if err != nil { + return err + } + defer s.Close() + + wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) + + msg := newIfInfomsg(syscall.AF_UNSPEC) + wb.AddData(msg) + + nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(name1)) + wb.AddData(nameData) + + txqLen := make([]byte, 4) + native.PutUint32(txqLen, uint32(txQueueLen)) + txqData := newRtAttr(syscall.IFLA_TXQLEN, txqLen) + wb.AddData(txqData) + + nest1 := newRtAttr(syscall.IFLA_LINKINFO, nil) + newRtAttrChild(nest1, IFLA_INFO_KIND, zeroTerminated("veth")) + nest2 := newRtAttrChild(nest1, IFLA_INFO_DATA, nil) + nest3 := newRtAttrChild(nest2, VETH_INFO_PEER, nil) + + newIfInfomsgChild(nest3, syscall.AF_UNSPEC) + newRtAttrChild(nest3, syscall.IFLA_IFNAME, zeroTerminated(name2)) + + txqLen2 := make([]byte, 4) + native.PutUint32(txqLen2, uint32(txQueueLen)) + newRtAttrChild(nest3, syscall.IFLA_TXQLEN, txqLen2) + + wb.AddData(nest1) + + if err := s.Send(wb); err != nil { + return err + } + + if err := s.HandleAck(wb.Seq); err != nil { + if os.IsExist(err) { + return ErrInterfaceExists + } + + return err + } + + return nil +} + +// Add a new VLAN interface with masterDev as its upper device +// This is identical to running: +// ip link add name $name link $masterdev type vlan id $id +func NetworkLinkAddVlan(masterDev, vlanDev string, vlanId uint16) error { + s, err := getNetlinkSocket() + if err != nil { + return err + } + defer s.Close() + + wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) + + masterDevIfc, err := net.InterfaceByName(masterDev) + if err != nil { + return err + } + + msg := newIfInfomsg(syscall.AF_UNSPEC) + wb.AddData(msg) + + nest1 := newRtAttr(syscall.IFLA_LINKINFO, nil) + newRtAttrChild(nest1, IFLA_INFO_KIND, nonZeroTerminated("vlan")) + + nest2 := newRtAttrChild(nest1, IFLA_INFO_DATA, nil) + vlanData := make([]byte, 2) + native.PutUint16(vlanData, vlanId) + newRtAttrChild(nest2, IFLA_VLAN_ID, vlanData) + wb.AddData(nest1) + + wb.AddData(uint32Attr(syscall.IFLA_LINK, uint32(masterDevIfc.Index))) + wb.AddData(newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(vlanDev))) + + if err := s.Send(wb); err != nil { + return err + } + return s.HandleAck(wb.Seq) +} + +// MacVlan link has LowerDev, UpperDev and operates in Mode mode +// This simplifies the code when creating MacVlan or MacVtap interface +type MacVlanLink struct { + MasterDev string + SlaveDev string + mode string +} + +func (m MacVlanLink) Mode() uint32 { + modeMap := map[string]uint32{ + "private": MACVLAN_MODE_PRIVATE, + "vepa": MACVLAN_MODE_VEPA, + "bridge": MACVLAN_MODE_BRIDGE, + "passthru": MACVLAN_MODE_PASSTHRU, + } + + return modeMap[m.mode] +} + +// Add MAC VLAN network interface with masterDev as its upper device +// This is identical to running: +// ip link add name $name link $masterdev type macvlan mode $mode +func networkLinkMacVlan(dev_type string, mcvln *MacVlanLink) error { + s, err := getNetlinkSocket() + if err != nil { + return err + } + defer s.Close() + + wb := newNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK) + + masterDevIfc, err := net.InterfaceByName(mcvln.MasterDev) + if err != nil { + return err + } + + msg := newIfInfomsg(syscall.AF_UNSPEC) + wb.AddData(msg) + + nest1 := newRtAttr(syscall.IFLA_LINKINFO, nil) + newRtAttrChild(nest1, IFLA_INFO_KIND, nonZeroTerminated(dev_type)) + + nest2 := newRtAttrChild(nest1, IFLA_INFO_DATA, nil) + macVlanData := make([]byte, 4) + native.PutUint32(macVlanData, mcvln.Mode()) + newRtAttrChild(nest2, IFLA_MACVLAN_MODE, macVlanData) + wb.AddData(nest1) + + wb.AddData(uint32Attr(syscall.IFLA_LINK, uint32(masterDevIfc.Index))) + wb.AddData(newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(mcvln.SlaveDev))) + + if err := s.Send(wb); err != nil { + return err + } + return s.HandleAck(wb.Seq) +} + +func NetworkLinkAddMacVlan(masterDev, macVlanDev string, mode string) error { + return networkLinkMacVlan("macvlan", &MacVlanLink{ + MasterDev: masterDev, + SlaveDev: macVlanDev, + mode: mode, + }) +} + +func NetworkLinkAddMacVtap(masterDev, macVlanDev string, mode string) error { + return networkLinkMacVlan("macvtap", &MacVlanLink{ + MasterDev: masterDev, + SlaveDev: macVlanDev, + mode: mode, + }) +} + +func networkLinkIpAction(action, flags int, ifa IfAddr) error { + s, err := getNetlinkSocket() + if err != nil { + return err + } + defer s.Close() + + family := getIpFamily(ifa.IP) + + wb := newNetlinkRequest(action, flags) + + msg := newIfAddrmsg(family) + msg.Index = uint32(ifa.Iface.Index) + prefixLen, _ := ifa.IPNet.Mask.Size() + msg.Prefixlen = uint8(prefixLen) + wb.AddData(msg) + + var ipData []byte + if family == syscall.AF_INET { + ipData = ifa.IP.To4() + } else { + ipData = ifa.IP.To16() + } + + localData := newRtAttr(syscall.IFA_LOCAL, ipData) + wb.AddData(localData) + + addrData := newRtAttr(syscall.IFA_ADDRESS, ipData) + wb.AddData(addrData) + + if err := s.Send(wb); err != nil { + return err + } + + return s.HandleAck(wb.Seq) +} + +func networkLinkIpAction4(action, flags int, ifa IfAddr, ifa_broadcast IfAddr) error { + s, err := getNetlinkSocket() + if err != nil { + return err + } + defer s.Close() + + family := getIpFamily(ifa.IP) + if family != syscall.AF_INET { + return errors.New("Address family has to be AF_INET (IPv4)") + } + + wb := newNetlinkRequest(action, flags) + + msg := newIfAddrmsg(family) + msg.Index = uint32(ifa.Iface.Index) + prefixLen, _ := ifa.IPNet.Mask.Size() + msg.Prefixlen = uint8(prefixLen) + wb.AddData(msg) + + + ipData := ifa.IP.To4() + + localData := newRtAttr(syscall.IFA_LOCAL, ipData) + wb.AddData(localData) + + addrData := newRtAttr(syscall.IFA_ADDRESS, ipData) + wb.AddData(addrData) + + + ipBcData := ifa_broadcast.IP.To4() + brAddrData := newRtAttr(syscall.IFA_BROADCAST, ipBcData) + wb.AddData(brAddrData) + + if err := s.Send(wb); err != nil { + return err + } + + return s.HandleAck(wb.Seq) +} + +// Delete an IP address from an interface. This is identical to: +// ip addr del $ip/$ipNet dev $iface +func NetworkLinkDelIp(iface *net.Interface, ip net.IP, ipNet *net.IPNet) error { + return networkLinkIpAction( + syscall.RTM_DELADDR, + syscall.NLM_F_ACK, + IfAddr{iface, ip, ipNet}, + ) +} + +func IpBroadcast4(n *net.IPNet) (net.IP, error) { + ipv4 := n.IP.To4() + if ipv4 == nil { + return nil, errors.New("No IPv4 net") + } + maskv4 := n.Mask + if len(maskv4) == net.IPv6len { + maskv4 = maskv4[12:] + } + + res := net.IPv4(0xff,0xff,0xff,0xff).To4() + for i:=0; i= IFNAMSIZ { + return fmt.Errorf("Interface name %s too long", name) + } + + s, err := getIfSocket() + if err != nil { + return err + } + defer syscall.Close(s) + + nameBytePtr, err := syscall.BytePtrFromString(name) + if err != nil { + return err + } + if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), SIOC_BRADDBR, uintptr(unsafe.Pointer(nameBytePtr))); err != 0 { + return err + } + if setMacAddr { + return SetMacAddress(name, randMacAddr()) + } + return nil +} + +// Delete the actual bridge device. +func DeleteBridge(name string) error { + s, err := getIfSocket() + if err != nil { + return err + } + defer syscall.Close(s) + + nameBytePtr, err := syscall.BytePtrFromString(name) + if err != nil { + return err + } + + var ifr ifreqFlags + copy(ifr.IfrnName[:len(ifr.IfrnName)-1], []byte(name)) + if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), + syscall.SIOCSIFFLAGS, uintptr(unsafe.Pointer(&ifr))); err != 0 { + return err + } + + if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), + SIOC_BRDELBR, uintptr(unsafe.Pointer(nameBytePtr))); err != 0 { + return err + } + return nil +} + +func ifIoctBridge(iface, master *net.Interface, op uintptr) error { + if len(master.Name) >= IFNAMSIZ { + return fmt.Errorf("Interface name %s too long", master.Name) + } + + s, err := getIfSocket() + if err != nil { + return err + } + defer syscall.Close(s) + + ifr := ifreqIndex{} + copy(ifr.IfrnName[:len(ifr.IfrnName)-1], master.Name) + ifr.IfruIndex = int32(iface.Index) + + if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), op, uintptr(unsafe.Pointer(&ifr))); err != 0 { + return err + } + + return nil +} + +// Add a slave to a bridge device. This is more backward-compatible than +// netlink.NetworkSetMaster and works on RHEL 6. +func AddToBridge(iface, master *net.Interface) error { + return ifIoctBridge(iface, master, SIOC_BRADDIF) +} + +// Detach a slave from a bridge device. This is more backward-compatible than +// netlink.NetworkSetMaster and works on RHEL 6. +func DelFromBridge(iface, master *net.Interface) error { + return ifIoctBridge(iface, master, SIOC_BRDELIF) +} + +func randMacAddr() string { + hw := make(net.HardwareAddr, 6) + for i := 0; i < 6; i++ { + hw[i] = byte(rnd.Intn(255)) + } + hw[0] &^= 0x1 // clear multicast bit + hw[0] |= 0x2 // set local assignment bit (IEEE802) + return hw.String() +} + +func SetMacAddress(name, addr string) error { + if len(name) >= IFNAMSIZ { + return fmt.Errorf("Interface name %s too long", name) + } + + hw, err := net.ParseMAC(addr) + if err != nil { + return err + } + + s, err := getIfSocket() + if err != nil { + return err + } + defer syscall.Close(s) + + ifr := ifreqHwaddr{} + ifr.IfruHwaddr.Family = syscall.ARPHRD_ETHER + copy(ifr.IfrnName[:len(ifr.IfrnName)-1], name) + + for i := 0; i < 6; i++ { + ifr.IfruHwaddr.Data[i] = ifrDataByte(hw[i]) + } + + if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), syscall.SIOCSIFHWADDR, uintptr(unsafe.Pointer(&ifr))); err != 0 { + return err + } + return nil +} + +func SetHairpinMode(iface *net.Interface, enabled bool) error { + s, err := getNetlinkSocket() + if err != nil { + return err + } + defer s.Close() + req := newNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK) + + msg := newIfInfomsg(syscall.AF_BRIDGE) + msg.Type = syscall.RTM_SETLINK + msg.Flags = syscall.NLM_F_REQUEST + msg.Index = int32(iface.Index) + msg.Change = DEFAULT_CHANGE + req.AddData(msg) + + mode := []byte{0} + if enabled { + mode[0] = byte(1) + } + + br := newRtAttr(syscall.IFLA_PROTINFO|syscall.NLA_F_NESTED, nil) + newRtAttrChild(br, IFLA_BRPORT_MODE, mode) + req.AddData(br) + if err := s.Send(req); err != nil { + return err + } + + return s.HandleAck(req.Seq) +} + +func ChangeName(iface *net.Interface, newName string) error { + if len(newName) >= IFNAMSIZ { + return fmt.Errorf("Interface name %s too long", newName) + } + + fd, err := getIfSocket() + if err != nil { + return err + } + defer syscall.Close(fd) + + data := [IFNAMSIZ * 2]byte{} + // the "-1"s here are very important for ensuring we get proper null + // termination of our new C strings + copy(data[:IFNAMSIZ-1], iface.Name) + copy(data[IFNAMSIZ:IFNAMSIZ*2-1], newName) + + if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), syscall.SIOCSIFNAME, uintptr(unsafe.Pointer(&data[0]))); errno != 0 { + return errno + } + + return nil +} diff --git a/netlink/netlink_linux_armppc64.go b/netlink/netlink_linux_armppc64.go new file mode 100644 index 0000000..965e0bf --- /dev/null +++ b/netlink/netlink_linux_armppc64.go @@ -0,0 +1,7 @@ +// +build arm ppc64 ppc64le + +package netlink + +func ifrDataByte(b byte) uint8 { + return uint8(b) +} diff --git a/netlink/netlink_linux_notarm.go b/netlink/netlink_linux_notarm.go new file mode 100644 index 0000000..7446279 --- /dev/null +++ b/netlink/netlink_linux_notarm.go @@ -0,0 +1,7 @@ +// +build !arm,!ppc64,!ppc64le + +package netlink + +func ifrDataByte(b byte) int8 { + return int8(b) +} diff --git a/netlink/netlink_linux_test.go b/netlink/netlink_linux_test.go new file mode 100644 index 0000000..3f6511a --- /dev/null +++ b/netlink/netlink_linux_test.go @@ -0,0 +1,408 @@ +package netlink + +import ( + "net" + "strings" + "syscall" + "testing" +) + +type testLink struct { + name string + linkType string +} + +func addLink(t *testing.T, name string, linkType string) { + if err := NetworkLinkAdd(name, linkType); err != nil { + t.Fatalf("Unable to create %s link: %s", name, err) + } +} + +func readLink(t *testing.T, name string) *net.Interface { + iface, err := net.InterfaceByName(name) + if err != nil { + t.Fatalf("Could not find %s interface: %s", name, err) + } + + return iface +} + +func deleteLink(t *testing.T, name string) { + if err := NetworkLinkDel(name); err != nil { + t.Fatalf("Unable to delete %s link: %s", name, err) + } +} + +func upLink(t *testing.T, name string) { + iface := readLink(t, name) + if err := NetworkLinkUp(iface); err != nil { + t.Fatalf("Could not bring UP %#v interface: %s", iface, err) + } +} + +func downLink(t *testing.T, name string) { + iface := readLink(t, name) + if err := NetworkLinkDown(iface); err != nil { + t.Fatalf("Could not bring DOWN %#v interface: %s", iface, err) + } +} + +func ipAssigned(iface *net.Interface, ip net.IP) bool { + addrs, _ := iface.Addrs() + + for _, addr := range addrs { + args := strings.SplitN(addr.String(), "/", 2) + if args[0] == ip.String() { + return true + } + } + + return false +} + +func TestNetworkLinkAddDel(t *testing.T) { + if testing.Short() { + return + } + + testLinks := []testLink{ + {"tstEth", "dummy"}, + {"tstBr", "bridge"}, + } + + for _, tl := range testLinks { + addLink(t, tl.name, tl.linkType) + defer deleteLink(t, tl.name) + readLink(t, tl.name) + } +} + +func TestNetworkLinkUpDown(t *testing.T) { + if testing.Short() { + return + } + + tl := testLink{name: "tstEth", linkType: "dummy"} + + addLink(t, tl.name, tl.linkType) + defer deleteLink(t, tl.name) + + upLink(t, tl.name) + ifcAfterUp := readLink(t, tl.name) + + if (ifcAfterUp.Flags & syscall.IFF_UP) != syscall.IFF_UP { + t.Fatalf("Could not bring UP %#v initerface", tl) + } + + downLink(t, tl.name) + ifcAfterDown := readLink(t, tl.name) + + if (ifcAfterDown.Flags & syscall.IFF_UP) == syscall.IFF_UP { + t.Fatalf("Could not bring DOWN %#v initerface", tl) + } +} + +func TestNetworkSetMacAddress(t *testing.T) { + if testing.Short() { + return + } + + tl := testLink{name: "tstEth", linkType: "dummy"} + macaddr := "22:ce:e0:99:63:6f" + + addLink(t, tl.name, tl.linkType) + defer deleteLink(t, tl.name) + + ifcBeforeSet := readLink(t, tl.name) + + if err := NetworkSetMacAddress(ifcBeforeSet, macaddr); err != nil { + t.Fatalf("Could not set %s MAC address on %#v interface: %s", macaddr, tl, err) + } + + ifcAfterSet := readLink(t, tl.name) + + if ifcAfterSet.HardwareAddr.String() != macaddr { + t.Fatalf("Could not set %s MAC address on %#v interface", macaddr, tl) + } +} + +func TestNetworkSetMTU(t *testing.T) { + if testing.Short() { + return + } + + tl := testLink{name: "tstEth", linkType: "dummy"} + mtu := 1400 + + addLink(t, tl.name, tl.linkType) + defer deleteLink(t, tl.name) + + ifcBeforeSet := readLink(t, tl.name) + + if err := NetworkSetMTU(ifcBeforeSet, mtu); err != nil { + t.Fatalf("Could not set %d MTU on %#v interface: %s", mtu, tl, err) + } + + ifcAfterSet := readLink(t, tl.name) + + if ifcAfterSet.MTU != mtu { + t.Fatalf("Could not set %d MTU on %#v interface", mtu, tl) + } +} + +func TestNetworkSetMasterNoMaster(t *testing.T) { + if testing.Short() { + return + } + + master := testLink{"tstBr", "bridge"} + slave := testLink{"tstEth", "dummy"} + testLinks := []testLink{master, slave} + + for _, tl := range testLinks { + addLink(t, tl.name, tl.linkType) + defer deleteLink(t, tl.name) + upLink(t, tl.name) + } + + masterIfc := readLink(t, master.name) + slaveIfc := readLink(t, slave.name) + if err := NetworkSetMaster(slaveIfc, masterIfc); err != nil { + t.Fatalf("Could not set %#v to be the master of %#v: %s", master, slave, err) + } + + // Trying to figure out a way to test which will not break on RHEL6. + // We could check for existence of /sys/class/net/tstEth/upper_tstBr + // which should point to the ../tstBr which is the UPPER device i.e. network bridge + + if err := NetworkSetNoMaster(slaveIfc); err != nil { + t.Fatalf("Could not UNset %#v master of %#v: %s", master, slave, err) + } +} + +func TestNetworkChangeName(t *testing.T) { + if testing.Short() { + return + } + + tl := testLink{"tstEth", "dummy"} + newName := "newTst" + + addLink(t, tl.name, tl.linkType) + + linkIfc := readLink(t, tl.name) + if err := NetworkChangeName(linkIfc, newName); err != nil { + deleteLink(t, tl.name) + t.Fatalf("Could not change %#v interface name to %s: %s", tl, newName, err) + } + + readLink(t, newName) + deleteLink(t, newName) +} + +func TestNetworkLinkAddVlan(t *testing.T) { + if testing.Short() { + return + } + + tl := struct { + name string + id uint16 + }{ + name: "tstVlan", + id: 32, + } + masterLink := testLink{"tstEth", "dummy"} + + addLink(t, masterLink.name, masterLink.linkType) + defer deleteLink(t, masterLink.name) + + if err := NetworkLinkAddVlan(masterLink.name, tl.name, tl.id); err != nil { + t.Fatalf("Unable to create %#v VLAN interface: %s", tl, err) + } + + readLink(t, tl.name) +} + +func TestNetworkLinkAddMacVlan(t *testing.T) { + if testing.Short() { + return + } + + tl := struct { + name string + mode string + }{ + name: "tstVlan", + mode: "private", + } + masterLink := testLink{"tstEth", "dummy"} + + addLink(t, masterLink.name, masterLink.linkType) + defer deleteLink(t, masterLink.name) + + if err := NetworkLinkAddMacVlan(masterLink.name, tl.name, tl.mode); err != nil { + t.Fatalf("Unable to create %#v MAC VLAN interface: %s", tl, err) + } + + readLink(t, tl.name) +} + +func TestNetworkLinkAddMacVtap(t *testing.T) { + if testing.Short() { + return + } + + tl := struct { + name string + mode string + }{ + name: "tstVtap", + mode: "private", + } + masterLink := testLink{"tstEth", "dummy"} + + addLink(t, masterLink.name, masterLink.linkType) + defer deleteLink(t, masterLink.name) + + if err := NetworkLinkAddMacVtap(masterLink.name, tl.name, tl.mode); err != nil { + t.Fatalf("Unable to create %#v MAC VTAP interface: %s", tl, err) + } + + readLink(t, tl.name) +} + +func TestAddDelNetworkIp(t *testing.T) { + if testing.Short() { + return + } + + ifaceName := "lo" + ip := net.ParseIP("127.0.1.1") + mask := net.IPv4Mask(255, 255, 255, 255) + ipNet := &net.IPNet{IP: ip, Mask: mask} + + iface, err := net.InterfaceByName(ifaceName) + if err != nil { + t.Skip("No 'lo' interface; skipping tests") + } + + if err := NetworkLinkAddIp(iface, ip, ipNet); err != nil { + t.Fatalf("Could not add IP address %s to interface %#v: %s", ip.String(), iface, err) + } + + if !ipAssigned(iface, ip) { + t.Fatalf("Could not locate address '%s' in lo address list.", ip.String()) + } + + if err := NetworkLinkDelIp(iface, ip, ipNet); err != nil { + t.Fatalf("Could not delete IP address %s from interface %#v: %s", ip.String(), iface, err) + } + + if ipAssigned(iface, ip) { + t.Fatalf("Located address '%s' in lo address list after removal.", ip.String()) + } +} + +func TestAddRouteSourceSelection(t *testing.T) { + tstIp := "127.1.1.1" + tl := testLink{name: "tstEth", linkType: "dummy"} + + addLink(t, tl.name, tl.linkType) + defer deleteLink(t, tl.name) + + ip := net.ParseIP(tstIp) + mask := net.IPv4Mask(255, 255, 255, 255) + ipNet := &net.IPNet{IP: ip, Mask: mask} + + iface, err := net.InterfaceByName(tl.name) + if err != nil { + t.Fatalf("Lost created link %#v", tl) + } + + if err := NetworkLinkAddIp(iface, ip, ipNet); err != nil { + t.Fatalf("Could not add IP address %s to interface %#v: %s", ip.String(), iface, err) + } + + upLink(t, tl.name) + defer downLink(t, tl.name) + + if err := AddRoute("127.0.0.0/8", tstIp, "", tl.name); err != nil { + t.Fatalf("Failed to add route with source address") + } +} + +func TestCreateVethPair(t *testing.T) { + if testing.Short() { + return + } + + var ( + name1 = "veth1" + name2 = "veth2" + ) + + if err := NetworkCreateVethPair(name1, name2, 0); err != nil { + t.Fatalf("Could not create veth pair %s %s: %s", name1, name2, err) + } + defer NetworkLinkDel(name1) + + readLink(t, name1) + readLink(t, name2) +} + +// +// netlink package tests which do not use RTNETLINK +// +func TestCreateBridgeWithMac(t *testing.T) { + if testing.Short() { + return + } + + name := "testbridge" + + if err := CreateBridge(name, true); err != nil { + t.Fatal(err) + } + + if _, err := net.InterfaceByName(name); err != nil { + t.Fatal(err) + } + + // cleanup and tests + + if err := DeleteBridge(name); err != nil { + t.Fatal(err) + } + + if _, err := net.InterfaceByName(name); err == nil { + t.Fatalf("expected error getting interface because %s bridge was deleted", name) + } +} + +func TestSetMacAddress(t *testing.T) { + if testing.Short() { + return + } + + name := "testmac" + mac := randMacAddr() + + if err := NetworkLinkAdd(name, "bridge"); err != nil { + t.Fatal(err) + } + defer NetworkLinkDel(name) + + if err := SetMacAddress(name, mac); err != nil { + t.Fatal(err) + } + + iface, err := net.InterfaceByName(name) + if err != nil { + t.Fatal(err) + } + + if iface.HardwareAddr.String() != mac { + t.Fatalf("mac address %q does not match %q", iface.HardwareAddr, mac) + } +} diff --git a/proto/grpc.pb.go b/proto/grpc.pb.go index eae1745..ee9ffa8 100644 --- a/proto/grpc.pb.go +++ b/proto/grpc.pb.go @@ -131,22 +131,23 @@ func (m *LEDSettings) GetBlinkCount() uint32 { // USB Gadget type GadgetSettings struct { - Enabled bool `protobuf:"varint,1,opt,name=enabled" json:"enabled,omitempty"` - Vid string `protobuf:"bytes,2,opt,name=vid" json:"vid,omitempty"` - Pid string `protobuf:"bytes,3,opt,name=pid" json:"pid,omitempty"` - Manufacturer string `protobuf:"bytes,4,opt,name=manufacturer" json:"manufacturer,omitempty"` - Product string `protobuf:"bytes,5,opt,name=product" json:"product,omitempty"` - Serial string `protobuf:"bytes,6,opt,name=serial" json:"serial,omitempty"` - Use_CDC_ECM bool `protobuf:"varint,7,opt,name=use_CDC_ECM,json=useCDCECM" json:"use_CDC_ECM,omitempty"` - Use_RNDIS bool `protobuf:"varint,8,opt,name=use_RNDIS,json=useRNDIS" json:"use_RNDIS,omitempty"` - Use_HID_KEYBOARD bool `protobuf:"varint,9,opt,name=use_HID_KEYBOARD,json=useHIDKEYBOARD" json:"use_HID_KEYBOARD,omitempty"` - Use_HID_MOUSE bool `protobuf:"varint,10,opt,name=use_HID_MOUSE,json=useHIDMOUSE" json:"use_HID_MOUSE,omitempty"` - Use_HID_RAW bool `protobuf:"varint,11,opt,name=use_HID_RAW,json=useHIDRAW" json:"use_HID_RAW,omitempty"` - Use_UMS bool `protobuf:"varint,12,opt,name=use_UMS,json=useUMS" json:"use_UMS,omitempty"` - Use_SERIAL bool `protobuf:"varint,13,opt,name=use_SERIAL,json=useSERIAL" json:"use_SERIAL,omitempty"` - RndisSettings *GadgetSettingsEthernet `protobuf:"bytes,14,opt,name=rndis_settings,json=rndisSettings" json:"rndis_settings,omitempty"` - CdcEcmSettings *GadgetSettingsEthernet `protobuf:"bytes,15,opt,name=cdc_ecm_settings,json=cdcEcmSettings" json:"cdc_ecm_settings,omitempty"` - UmsSettings *GadgetSettingsUMS `protobuf:"bytes,16,opt,name=ums_settings,json=umsSettings" json:"ums_settings,omitempty"` + Enabled bool `protobuf:"varint,1,opt,name=enabled" json:"enabled,omitempty"` + Vid string `protobuf:"bytes,2,opt,name=vid" json:"vid,omitempty"` + Pid string `protobuf:"bytes,3,opt,name=pid" json:"pid,omitempty"` + Manufacturer string `protobuf:"bytes,4,opt,name=manufacturer" json:"manufacturer,omitempty"` + Product string `protobuf:"bytes,5,opt,name=product" json:"product,omitempty"` + Serial string `protobuf:"bytes,6,opt,name=serial" json:"serial,omitempty"` + Use_CDC_ECM bool `protobuf:"varint,7,opt,name=use_CDC_ECM,json=useCDCECM" json:"use_CDC_ECM,omitempty"` + Use_RNDIS bool `protobuf:"varint,8,opt,name=use_RNDIS,json=useRNDIS" json:"use_RNDIS,omitempty"` + Use_HID_KEYBOARD bool `protobuf:"varint,9,opt,name=use_HID_KEYBOARD,json=useHIDKEYBOARD" json:"use_HID_KEYBOARD,omitempty"` + Use_HID_MOUSE bool `protobuf:"varint,10,opt,name=use_HID_MOUSE,json=useHIDMOUSE" json:"use_HID_MOUSE,omitempty"` + Use_HID_RAW bool `protobuf:"varint,11,opt,name=use_HID_RAW,json=useHIDRAW" json:"use_HID_RAW,omitempty"` + Use_UMS bool `protobuf:"varint,12,opt,name=use_UMS,json=useUMS" json:"use_UMS,omitempty"` + Use_SERIAL bool `protobuf:"varint,13,opt,name=use_SERIAL,json=useSERIAL" json:"use_SERIAL,omitempty"` + RndisSettings *GadgetSettingsEthernet `protobuf:"bytes,14,opt,name=rndis_settings,json=rndisSettings" json:"rndis_settings,omitempty"` + CdcEcmSettings *GadgetSettingsEthernet `protobuf:"bytes,15,opt,name=cdc_ecm_settings,json=cdcEcmSettings" json:"cdc_ecm_settings,omitempty"` + UmsSettings *GadgetSettingsUMS `protobuf:"bytes,16,opt,name=ums_settings,json=umsSettings" json:"ums_settings,omitempty"` + EthernetSettings *EthernetInterfaceSettings `protobuf:"bytes,17,opt,name=ethernet_settings,json=ethernetSettings" json:"ethernet_settings,omitempty"` } func (m *GadgetSettings) Reset() { *m = GadgetSettings{} } @@ -266,6 +267,13 @@ func (m *GadgetSettings) GetUmsSettings() *GadgetSettingsUMS { return nil } +func (m *GadgetSettings) GetEthernetSettings() *EthernetInterfaceSettings { + if m != nil { + return m.EthernetSettings + } + return nil +} + type GadgetSettingsEthernet struct { HostAddr string `protobuf:"bytes,1,opt,name=host_addr,json=hostAddr" json:"host_addr,omitempty"` DevAddr string `protobuf:"bytes,2,opt,name=dev_addr,json=devAddr" json:"dev_addr,omitempty"` @@ -319,7 +327,8 @@ type EthernetInterfaceSettings struct { Mode EthernetInterfaceSettings_Mode `protobuf:"varint,2,opt,name=mode,enum=P4wnP1_grpc.EthernetInterfaceSettings_Mode" json:"mode,omitempty"` IpAddress4 string `protobuf:"bytes,3,opt,name=ipAddress4" json:"ipAddress4,omitempty"` Netmask4 string `protobuf:"bytes,4,opt,name=netmask4" json:"netmask4,omitempty"` - DhcpServerSettings *DHCPServerSettings `protobuf:"bytes,5,opt,name=dhcpServerSettings" json:"dhcpServerSettings,omitempty"` + Enabled bool `protobuf:"varint,5,opt,name=enabled" json:"enabled,omitempty"` + DhcpServerSettings *DHCPServerSettings `protobuf:"bytes,6,opt,name=dhcpServerSettings" json:"dhcpServerSettings,omitempty"` } func (m *EthernetInterfaceSettings) Reset() { *m = EthernetInterfaceSettings{} } @@ -355,6 +364,13 @@ func (m *EthernetInterfaceSettings) GetNetmask4() string { return "" } +func (m *EthernetInterfaceSettings) GetEnabled() bool { + if m != nil { + return m.Enabled + } + return false +} + func (m *EthernetInterfaceSettings) GetDhcpServerSettings() *DHCPServerSettings { if m != nil { return m.DhcpServerSettings @@ -896,83 +912,84 @@ var _P4WNP1_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("grpc.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 1237 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x5d, 0x6f, 0xdb, 0x36, - 0x17, 0x8e, 0x1d, 0xc7, 0x1f, 0xc7, 0x8e, 0xa3, 0xb2, 0x7d, 0x5b, 0x35, 0xfd, 0xca, 0xab, 0x75, - 0x43, 0xb0, 0x15, 0x06, 0xea, 0xe5, 0xa2, 0x28, 0x30, 0x6c, 0xaa, 0xad, 0xc4, 0x5e, 0x63, 0x5b, - 0x90, 0xe2, 0x06, 0xbb, 0x12, 0x18, 0x91, 0x8d, 0x89, 0x58, 0x1f, 0x10, 0xa9, 0x74, 0xb9, 0xdf, - 0x3f, 0xda, 0x2f, 0xda, 0xc5, 0x7e, 0xc7, 0x06, 0x52, 0xb2, 0x62, 0x27, 0x4e, 0x3b, 0x6c, 0x77, - 0x3c, 0xcf, 0x79, 0xce, 0xc3, 0x43, 0x1e, 0x1e, 0x92, 0x00, 0xe7, 0x49, 0xec, 0x77, 0xe2, 0x24, - 0x12, 0x11, 0x6a, 0xda, 0x07, 0x9f, 0x42, 0xfb, 0xb5, 0x27, 0x21, 0xa3, 0x03, 0xcd, 0x63, 0xab, - 0xef, 0x52, 0x21, 0x58, 0x78, 0xce, 0xd1, 0x0b, 0x68, 0x9e, 0xcd, 0x59, 0x78, 0xe1, 0xf9, 0x51, - 0x1a, 0x0a, 0xbd, 0xb4, 0x57, 0xda, 0xdf, 0x76, 0x40, 0x41, 0x3d, 0x89, 0x18, 0x7f, 0x56, 0xa0, - 0x7d, 0x84, 0xc9, 0x39, 0x15, 0x45, 0x8c, 0x0e, 0x35, 0x1a, 0xe2, 0xb3, 0x39, 0x25, 0x8a, 0x5f, - 0x77, 0x16, 0x26, 0xd2, 0x60, 0xf3, 0x92, 0x11, 0xbd, 0xbc, 0x57, 0xda, 0x6f, 0x38, 0x72, 0x28, - 0x91, 0x98, 0x11, 0x7d, 0x33, 0x43, 0x62, 0x46, 0x90, 0x01, 0xad, 0x00, 0x87, 0xe9, 0x47, 0xec, - 0x8b, 0x34, 0xa1, 0x89, 0x5e, 0x51, 0xae, 0x15, 0x4c, 0xce, 0x10, 0x27, 0x11, 0x49, 0x7d, 0xa1, - 0x6f, 0x29, 0xf7, 0xc2, 0x44, 0x0f, 0xa1, 0xca, 0x69, 0xc2, 0xf0, 0x5c, 0xaf, 0x2a, 0x47, 0x6e, - 0xa1, 0xe7, 0xd0, 0x4c, 0x39, 0xf5, 0x7a, 0xfd, 0x9e, 0x67, 0xf5, 0x46, 0x7a, 0x4d, 0xe5, 0xd5, - 0x48, 0x39, 0xed, 0xf5, 0x7b, 0x56, 0x6f, 0x84, 0x9e, 0x80, 0x34, 0x3c, 0x67, 0xdc, 0x1f, 0xba, - 0x7a, 0x5d, 0x79, 0xeb, 0x29, 0xa7, 0xca, 0x46, 0xfb, 0xa0, 0x49, 0xe7, 0x60, 0xd8, 0xf7, 0xde, - 0x5b, 0xbf, 0xbc, 0x9b, 0x98, 0x4e, 0x5f, 0x6f, 0x28, 0x4e, 0x3b, 0xe5, 0x74, 0x30, 0xec, 0x2f, - 0x50, 0x64, 0xc0, 0xf6, 0x82, 0x39, 0x9a, 0x4c, 0x5d, 0x4b, 0x07, 0x45, 0x6b, 0x66, 0x34, 0x05, - 0x2d, 0x52, 0x91, 0x1c, 0xc7, 0x3c, 0xd5, 0x9b, 0x45, 0x2a, 0x83, 0x61, 0xdf, 0x31, 0x4f, 0xd1, - 0x23, 0xa8, 0x49, 0xff, 0x74, 0xe4, 0xea, 0x2d, 0xe5, 0xab, 0xa6, 0x9c, 0x4e, 0x47, 0x2e, 0x7a, - 0x06, 0x20, 0x1d, 0xae, 0xe5, 0x0c, 0xcd, 0x63, 0x7d, 0xbb, 0x88, 0xcb, 0x00, 0xf4, 0x33, 0xb4, - 0x93, 0x90, 0x30, 0xee, 0xf1, 0xbc, 0x10, 0x7a, 0x7b, 0xaf, 0xb4, 0xdf, 0xec, 0x7e, 0xd5, 0x59, - 0xaa, 0x6f, 0x67, 0xb5, 0x56, 0x96, 0x98, 0xd1, 0x24, 0xa4, 0xc2, 0xd9, 0x56, 0xa1, 0x45, 0x09, - 0x47, 0xa0, 0xf9, 0xc4, 0xf7, 0xa8, 0x1f, 0x5c, 0xab, 0xed, 0xfc, 0x73, 0xb5, 0xb6, 0x4f, 0x7c, - 0xcb, 0x0f, 0x0a, 0x39, 0x13, 0x5a, 0x69, 0xb0, 0x94, 0x98, 0xa6, 0xa4, 0x9e, 0x7f, 0x46, 0x6a, - 0x3a, 0x72, 0x9d, 0x66, 0x1a, 0x14, 0x19, 0x19, 0x36, 0x3c, 0x5c, 0x3f, 0x99, 0x2c, 0xdd, 0x2c, - 0xe2, 0xc2, 0xc3, 0x84, 0x24, 0xea, 0xc0, 0x35, 0x9c, 0xba, 0x04, 0x4c, 0x42, 0x12, 0xf4, 0x18, - 0xea, 0x84, 0x5e, 0x66, 0xbe, 0xec, 0xd8, 0xd5, 0x08, 0xbd, 0x94, 0x2e, 0xe3, 0x07, 0xb8, 0x77, - 0x6b, 0x4e, 0xf4, 0x00, 0xb6, 0x7c, 0x92, 0x44, 0x41, 0x7e, 0x72, 0x33, 0x03, 0x21, 0xa8, 0x7c, - 0x64, 0x73, 0x9a, 0x2b, 0xa8, 0xb1, 0xf1, 0x7b, 0x19, 0x1e, 0x2f, 0x72, 0x18, 0x86, 0x82, 0x26, - 0x1f, 0xb1, 0x4f, 0x8b, 0x15, 0x23, 0xa8, 0x84, 0x38, 0xa0, 0x79, 0x3e, 0x6a, 0x8c, 0x7e, 0x84, - 0x4a, 0x10, 0x91, 0x4c, 0xa5, 0xdd, 0xfd, 0x6e, 0x65, 0xf5, 0x77, 0x2a, 0x75, 0x46, 0x11, 0xa1, - 0x8e, 0x0a, 0x44, 0xcf, 0x01, 0x58, 0x2c, 0x73, 0xa7, 0x9c, 0x1f, 0xe4, 0x3d, 0xb3, 0x84, 0xa0, - 0x5d, 0xa8, 0x87, 0x54, 0x04, 0x98, 0x5f, 0x1c, 0xe4, 0x6d, 0x53, 0xd8, 0x68, 0x02, 0x88, 0xcc, - 0xfc, 0xd8, 0xa5, 0xc9, 0x25, 0x4d, 0x16, 0xe2, 0xaa, 0x7b, 0x9a, 0xdd, 0x17, 0x2b, 0xa9, 0xf4, - 0x07, 0x3d, 0x7b, 0x95, 0xe6, 0xac, 0x09, 0x35, 0x0e, 0xa0, 0x22, 0x53, 0x43, 0x00, 0xd5, 0x91, - 0x39, 0x9e, 0x9a, 0xc7, 0xda, 0x06, 0xda, 0x81, 0xa6, 0x8c, 0xf6, 0x7a, 0xc7, 0x43, 0x6b, 0x7c, - 0xa2, 0x95, 0x0a, 0xc0, 0xb5, 0x9c, 0x0f, 0x96, 0xa3, 0x95, 0x8d, 0xbf, 0x36, 0x01, 0xdd, 0x9e, - 0x40, 0xae, 0x6c, 0xce, 0xb8, 0xa0, 0xa1, 0x1d, 0x25, 0xc5, 0x2d, 0x73, 0x8d, 0xa0, 0x7d, 0xd8, - 0xc9, 0xac, 0x62, 0x7f, 0xf2, 0x5a, 0xdc, 0x84, 0xd1, 0x53, 0x68, 0xcc, 0x29, 0xe6, 0xf4, 0x50, - 0xd6, 0x2b, 0xdb, 0xa2, 0x6b, 0x00, 0x7d, 0x0b, 0x5a, 0x18, 0x09, 0x33, 0x15, 0xb3, 0x28, 0x61, - 0x02, 0x0b, 0x76, 0x49, 0xd5, 0x4e, 0xd5, 0x9d, 0x5b, 0x38, 0xea, 0x00, 0x22, 0xd1, 0x38, 0x12, - 0xef, 0x58, 0x48, 0xae, 0xa7, 0xdd, 0x52, 0xec, 0x35, 0x1e, 0xf4, 0x0d, 0xb4, 0x7d, 0x3c, 0x9f, - 0x9f, 0x61, 0xff, 0xc2, 0xf5, 0x13, 0x16, 0x8b, 0xfc, 0x0a, 0xba, 0x81, 0xa2, 0x03, 0xa8, 0x26, - 0x38, 0x3c, 0xa7, 0x5c, 0xaf, 0xed, 0x6d, 0xee, 0x37, 0xbb, 0x4f, 0xef, 0xd8, 0x7d, 0x47, 0x92, - 0x9c, 0x9c, 0x8b, 0x0e, 0xa1, 0x16, 0xc5, 0x82, 0x45, 0x21, 0xd7, 0xeb, 0x2a, 0xec, 0xd5, 0x17, - 0x8a, 0xd6, 0x99, 0x64, 0x74, 0x2b, 0x14, 0xc9, 0x95, 0xb3, 0x08, 0x46, 0x3d, 0x68, 0x72, 0xb9, - 0x40, 0x7f, 0x10, 0x71, 0xc1, 0xf5, 0x86, 0xd2, 0xfa, 0xff, 0x5d, 0x5a, 0x05, 0xd3, 0x59, 0x8e, - 0xda, 0x7d, 0x0b, 0xad, 0x65, 0x75, 0x79, 0x8b, 0x5f, 0xd0, 0xab, 0xbc, 0x6e, 0x72, 0x28, 0xfb, - 0xe8, 0x12, 0xcf, 0xd3, 0x45, 0x99, 0x32, 0xe3, 0x6d, 0xf9, 0x4d, 0xc9, 0x88, 0x60, 0xe7, 0xc6, - 0x1a, 0x65, 0xf5, 0xd5, 0x2a, 0x8f, 0xa3, 0x4f, 0x74, 0xd1, 0xc2, 0x4b, 0x48, 0xe1, 0x9f, 0xc6, - 0x31, 0x5d, 0xb4, 0xf1, 0x12, 0x52, 0xd4, 0xfc, 0x84, 0x05, 0xab, 0x35, 0x97, 0x80, 0xf1, 0x06, - 0x1e, 0xac, 0x5b, 0x91, 0x4c, 0x3a, 0xc0, 0x7e, 0x3e, 0x9d, 0x1c, 0xa2, 0x36, 0x94, 0x59, 0x9c, - 0xeb, 0x97, 0x59, 0x6c, 0xfc, 0xb1, 0x09, 0xad, 0x53, 0x76, 0xc8, 0x8a, 0x63, 0xfa, 0x14, 0x1a, - 0x84, 0x61, 0xbe, 0xfc, 0xb6, 0x5d, 0x03, 0x52, 0x30, 0xa1, 0xe7, 0x8b, 0xd7, 0x2d, 0xa1, 0xe7, - 0xa8, 0x9b, 0x77, 0xfc, 0xa6, 0xea, 0xf8, 0xd5, 0xfb, 0x6e, 0x59, 0x78, 0xb9, 0xc9, 0x1f, 0x41, - 0x0d, 0xc7, 0x1e, 0xe7, 0x8c, 0xe4, 0x3d, 0x5c, 0xc5, 0xb1, 0xcb, 0x19, 0x41, 0x26, 0x34, 0x70, - 0x2a, 0x66, 0x9e, 0x52, 0xdc, 0x52, 0x8a, 0x2f, 0xef, 0x56, 0x34, 0x6d, 0x79, 0x9a, 0x95, 0x6e, - 0x1d, 0xe7, 0x23, 0xf9, 0x82, 0xe0, 0xd8, 0xf3, 0x67, 0x38, 0x0c, 0x69, 0xf6, 0x42, 0x6e, 0x3b, - 0x0d, 0x1c, 0xf7, 0x32, 0x00, 0xfd, 0x0f, 0xaa, 0x38, 0xf6, 0x62, 0x7e, 0xa1, 0xde, 0xc7, 0x86, - 0xb3, 0x85, 0x63, 0x9b, 0x5f, 0xa0, 0x3d, 0x68, 0xe1, 0xd8, 0x9b, 0x31, 0x42, 0xb3, 0xb4, 0xb2, - 0xe7, 0x11, 0x70, 0x3c, 0x60, 0x84, 0xaa, 0xd4, 0x5e, 0x40, 0xd3, 0x9f, 0x33, 0x1a, 0x8a, 0x8c, - 0xd0, 0xc8, 0x2a, 0x94, 0x41, 0x8a, 0xf0, 0x0c, 0x72, 0x4b, 0xa9, 0x43, 0x56, 0xa2, 0x0c, 0x91, - 0x33, 0x7c, 0x0d, 0x6d, 0xc2, 0xd4, 0x2e, 0x7a, 0x21, 0xfd, 0x35, 0x88, 0xc2, 0xfc, 0x55, 0xdc, - 0xce, 0xd1, 0xb1, 0x02, 0x8d, 0x57, 0xf9, 0x95, 0x53, 0x85, 0xb2, 0x69, 0x6b, 0x1b, 0xa8, 0x06, - 0x9b, 0xee, 0x89, 0xa9, 0x95, 0xd0, 0x7d, 0xd8, 0x71, 0x4f, 0x4c, 0xef, 0xd0, 0x1c, 0x1e, 0x4f, - 0x3e, 0x58, 0x8e, 0x67, 0xda, 0x5a, 0xd9, 0x78, 0x09, 0x70, 0xbd, 0x09, 0xa8, 0x05, 0xf5, 0x53, - 0xdb, 0xec, 0x7a, 0xb6, 0xfb, 0x5e, 0xdb, 0x40, 0x75, 0xa8, 0x4c, 0x6c, 0x6b, 0xac, 0x95, 0x8c, - 0x1a, 0x6c, 0x59, 0x41, 0x2c, 0xae, 0xba, 0xbf, 0x55, 0xa0, 0x6a, 0x1f, 0x9c, 0x8e, 0xed, 0xd7, - 0x68, 0x04, 0xfa, 0x11, 0x15, 0x7d, 0x1a, 0xcf, 0xa3, 0x2b, 0x4a, 0x56, 0x1e, 0x09, 0x84, 0x56, - 0xaf, 0x6d, 0x19, 0xba, 0xfb, 0xe4, 0x33, 0x0f, 0x99, 0xb1, 0x81, 0x06, 0x70, 0x3f, 0xd3, 0xfa, - 0xcf, 0x4a, 0x87, 0x70, 0xef, 0x88, 0x8a, 0x1b, 0xdf, 0xad, 0x7f, 0xa1, 0x33, 0x81, 0x7b, 0xee, - 0x2d, 0x9d, 0xcf, 0xc5, 0x7c, 0x49, 0xf0, 0x27, 0x68, 0x1f, 0x51, 0xb1, 0xfc, 0x71, 0x5c, 0x97, - 0x95, 0xbe, 0x82, 0x2d, 0xb1, 0x33, 0x05, 0x77, 0x55, 0xe1, 0x4e, 0xf6, 0xee, 0x1a, 0x6d, 0x63, - 0x03, 0xf5, 0xa1, 0x35, 0x92, 0x5f, 0xd2, 0xe9, 0xc8, 0x55, 0x77, 0xfd, 0x17, 0xbe, 0x17, 0xeb, - 0x55, 0xce, 0xaa, 0xea, 0x4f, 0xfc, 0xfd, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb7, 0x27, 0x83, - 0xd2, 0x21, 0x0b, 0x00, 0x00, + // 1261 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x6d, 0x6f, 0xdb, 0xb6, + 0x13, 0x8f, 0x9d, 0xf8, 0xe9, 0xec, 0x38, 0x0a, 0xdb, 0x7f, 0xab, 0xa6, 0x4f, 0xf9, 0x6b, 0x5d, + 0x11, 0x6c, 0x85, 0x81, 0x7a, 0x79, 0x51, 0x14, 0x18, 0x36, 0xd5, 0x56, 0x62, 0xaf, 0xb1, 0x2d, + 0x48, 0x71, 0x83, 0xbd, 0x12, 0x18, 0x91, 0x8d, 0x89, 0xd8, 0x92, 0x20, 0x52, 0xe9, 0xf2, 0x7e, + 0x9f, 0x6a, 0xdf, 0x61, 0x1f, 0x62, 0x9f, 0x64, 0x03, 0x29, 0xc9, 0x0f, 0x89, 0xd3, 0x16, 0xdb, + 0x3b, 0xde, 0xef, 0xee, 0x7e, 0x3c, 0xf2, 0x78, 0x77, 0x04, 0xb8, 0x88, 0x23, 0xbf, 0x15, 0xc5, + 0xa1, 0x08, 0x51, 0xdd, 0x3e, 0xfc, 0x14, 0xd8, 0xaf, 0x3d, 0x09, 0x19, 0x2d, 0xa8, 0x9f, 0x58, + 0x5d, 0x97, 0x0a, 0xc1, 0x82, 0x0b, 0x8e, 0x9e, 0x43, 0xfd, 0x7c, 0xca, 0x82, 0x4b, 0xcf, 0x0f, + 0x93, 0x40, 0xe8, 0x85, 0xfd, 0xc2, 0xc1, 0xb6, 0x03, 0x0a, 0xea, 0x48, 0xc4, 0xf8, 0xa3, 0x04, + 0xcd, 0x63, 0x4c, 0x2e, 0xa8, 0x98, 0xfb, 0xe8, 0x50, 0xa1, 0x01, 0x3e, 0x9f, 0x52, 0xa2, 0xec, + 0xab, 0x4e, 0x2e, 0x22, 0x0d, 0x36, 0xaf, 0x18, 0xd1, 0x8b, 0xfb, 0x85, 0x83, 0x9a, 0x23, 0x97, + 0x12, 0x89, 0x18, 0xd1, 0x37, 0x53, 0x24, 0x62, 0x04, 0x19, 0xd0, 0x98, 0xe1, 0x20, 0xf9, 0x88, + 0x7d, 0x91, 0xc4, 0x34, 0xd6, 0xb7, 0x94, 0x6a, 0x05, 0x93, 0x3b, 0x44, 0x71, 0x48, 0x12, 0x5f, + 0xe8, 0x25, 0xa5, 0xce, 0x45, 0xf4, 0x00, 0xca, 0x9c, 0xc6, 0x0c, 0x4f, 0xf5, 0xb2, 0x52, 0x64, + 0x12, 0x7a, 0x06, 0xf5, 0x84, 0x53, 0xaf, 0xd3, 0xed, 0x78, 0x56, 0x67, 0xa0, 0x57, 0x54, 0x5c, + 0xb5, 0x84, 0xd3, 0x4e, 0xb7, 0x63, 0x75, 0x06, 0xe8, 0x31, 0x48, 0xc1, 0x73, 0x86, 0xdd, 0xbe, + 0xab, 0x57, 0x95, 0xb6, 0x9a, 0x70, 0xaa, 0x64, 0x74, 0x00, 0x9a, 0x54, 0xf6, 0xfa, 0x5d, 0xef, + 0xbd, 0xf5, 0xeb, 0xbb, 0x91, 0xe9, 0x74, 0xf5, 0x9a, 0xb2, 0x69, 0x26, 0x9c, 0xf6, 0xfa, 0xdd, + 0x1c, 0x45, 0x06, 0x6c, 0xe7, 0x96, 0x83, 0xd1, 0xd8, 0xb5, 0x74, 0x50, 0x66, 0xf5, 0xd4, 0x4c, + 0x41, 0x79, 0x28, 0xd2, 0xc6, 0x31, 0xcf, 0xf4, 0xfa, 0x3c, 0x94, 0x5e, 0xbf, 0xeb, 0x98, 0x67, + 0xe8, 0x21, 0x54, 0xa4, 0x7e, 0x3c, 0x70, 0xf5, 0x86, 0xd2, 0x95, 0x13, 0x4e, 0xc7, 0x03, 0x17, + 0x3d, 0x05, 0x90, 0x0a, 0xd7, 0x72, 0xfa, 0xe6, 0x89, 0xbe, 0x3d, 0xf7, 0x4b, 0x01, 0xf4, 0x0b, + 0x34, 0xe3, 0x80, 0x30, 0xee, 0xf1, 0x2c, 0x11, 0x7a, 0x73, 0xbf, 0x70, 0x50, 0x6f, 0x7f, 0xd3, + 0x5a, 0xca, 0x6f, 0x6b, 0x35, 0x57, 0x96, 0x98, 0xd0, 0x38, 0xa0, 0xc2, 0xd9, 0x56, 0xae, 0xf3, + 0x14, 0x0e, 0x40, 0xf3, 0x89, 0xef, 0x51, 0x7f, 0xb6, 0x60, 0xdb, 0xf9, 0x7a, 0xb6, 0xa6, 0x4f, + 0x7c, 0xcb, 0x9f, 0xcd, 0xe9, 0x4c, 0x68, 0x24, 0xb3, 0xa5, 0xc0, 0x34, 0x45, 0xf5, 0xec, 0x33, + 0x54, 0xe3, 0x81, 0xeb, 0xd4, 0x93, 0xd9, 0x22, 0x22, 0x17, 0x76, 0x69, 0x46, 0xbf, 0xe0, 0xd9, + 0x55, 0x3c, 0x2f, 0x57, 0x78, 0xf2, 0x20, 0xfa, 0x81, 0xa0, 0xf1, 0x47, 0xec, 0xd3, 0x9c, 0xc2, + 0xd1, 0x72, 0x82, 0x1c, 0x31, 0x6c, 0x78, 0xb0, 0xfe, 0x04, 0xf2, 0x3d, 0x4c, 0x42, 0x2e, 0x3c, + 0x4c, 0x48, 0xac, 0x5e, 0x71, 0xcd, 0xa9, 0x4a, 0xc0, 0x24, 0x24, 0x46, 0x8f, 0xa0, 0x4a, 0xe8, + 0x55, 0xaa, 0x4b, 0xdf, 0x72, 0x85, 0xd0, 0x2b, 0xa9, 0x32, 0x7e, 0x84, 0xdd, 0x5b, 0x07, 0x41, + 0xf7, 0xa1, 0xe4, 0x93, 0x38, 0x9c, 0x65, 0xe5, 0x90, 0x0a, 0x08, 0xc1, 0xd6, 0x47, 0x36, 0xa5, + 0x19, 0x83, 0x5a, 0x1b, 0x7f, 0x16, 0xe1, 0xd1, 0x9d, 0x07, 0x90, 0x1e, 0x01, 0x9e, 0xd1, 0x2c, + 0x1e, 0xb5, 0x46, 0x3f, 0xc1, 0xd6, 0x2c, 0x24, 0x29, 0x4b, 0xb3, 0xfd, 0xfd, 0xd7, 0x5d, 0x45, + 0x6b, 0x10, 0x12, 0xea, 0x28, 0x47, 0xf4, 0x0c, 0x80, 0x45, 0x32, 0x76, 0xca, 0xf9, 0x61, 0x56, + 0x88, 0x4b, 0x08, 0xda, 0x83, 0x6a, 0x40, 0xc5, 0x0c, 0xf3, 0xcb, 0xc3, 0xac, 0x16, 0xe7, 0xf2, + 0x72, 0xa5, 0x97, 0x56, 0x2b, 0x7d, 0x04, 0x88, 0x4c, 0xfc, 0xc8, 0xa5, 0xf1, 0x15, 0x8d, 0xf3, + 0x6d, 0x55, 0x4d, 0xd6, 0xdb, 0xcf, 0x57, 0x82, 0xec, 0xf6, 0x3a, 0xf6, 0xaa, 0x99, 0xb3, 0xc6, + 0xd5, 0x38, 0x84, 0x2d, 0x19, 0x34, 0x02, 0x28, 0x0f, 0xcc, 0xe1, 0xd8, 0x3c, 0xd1, 0x36, 0xd0, + 0x0e, 0xd4, 0xa5, 0xb7, 0xd7, 0x39, 0xe9, 0x5b, 0xc3, 0x53, 0xad, 0x30, 0x07, 0x5c, 0xcb, 0xf9, + 0x60, 0x39, 0x5a, 0xd1, 0xf8, 0x7b, 0x13, 0xd0, 0xed, 0x0d, 0xe4, 0x99, 0xa7, 0x8c, 0x0b, 0x1a, + 0xd8, 0x61, 0x3c, 0x6f, 0x6a, 0x0b, 0x04, 0x1d, 0xc0, 0x4e, 0x2a, 0xcd, 0x6f, 0x2e, 0xcb, 0xd2, + 0x4d, 0x18, 0x3d, 0x81, 0xda, 0x94, 0x62, 0x4e, 0x8f, 0x64, 0x26, 0xd3, 0xcb, 0x5b, 0x00, 0xe8, + 0x3b, 0xd0, 0x82, 0x50, 0x98, 0x89, 0x98, 0x84, 0x31, 0x13, 0x58, 0xb0, 0x2b, 0xaa, 0xee, 0xb0, + 0xea, 0xdc, 0xc2, 0x51, 0x0b, 0x10, 0x09, 0x87, 0xa1, 0x78, 0xc7, 0x02, 0xb2, 0xd8, 0x36, 0xbd, + 0xd6, 0x35, 0x1a, 0xf4, 0x12, 0x9a, 0x3e, 0x9e, 0x4e, 0xcf, 0xb1, 0x7f, 0xe9, 0xfa, 0x31, 0x8b, + 0x44, 0xd6, 0xf1, 0x6e, 0xa0, 0xe8, 0x10, 0xca, 0x31, 0x0e, 0x2e, 0x28, 0xd7, 0x2b, 0xfb, 0x9b, + 0x07, 0xf5, 0xf6, 0x93, 0x3b, 0x6e, 0xdf, 0x91, 0x46, 0x4e, 0x66, 0x8b, 0x8e, 0xa0, 0x12, 0x46, + 0x82, 0x85, 0x01, 0xd7, 0xab, 0xca, 0xed, 0xd5, 0x17, 0x92, 0xd6, 0x1a, 0xa5, 0xe6, 0x56, 0x20, + 0xe2, 0x6b, 0x27, 0x77, 0x46, 0x1d, 0xa8, 0x73, 0x79, 0x40, 0xbf, 0x17, 0x72, 0xc1, 0xf5, 0x9a, + 0xe2, 0xfa, 0xff, 0x5d, 0x5c, 0x73, 0x4b, 0x67, 0xd9, 0x6b, 0xef, 0x2d, 0x34, 0x96, 0xd9, 0xe5, + 0xd0, 0xb8, 0xa4, 0xd7, 0x59, 0xde, 0xe4, 0x52, 0x56, 0xd8, 0x15, 0x9e, 0x26, 0x79, 0x9a, 0x52, + 0xe1, 0x6d, 0xf1, 0x4d, 0xc1, 0x08, 0x61, 0xe7, 0xc6, 0x19, 0x65, 0xf6, 0xd5, 0x29, 0x4f, 0xc2, + 0x4f, 0x34, 0x2f, 0xee, 0x25, 0x64, 0xae, 0x1f, 0x47, 0x11, 0xcd, 0x0b, 0x7c, 0x09, 0x99, 0xe7, + 0xfc, 0x94, 0xcd, 0x56, 0x73, 0x2e, 0x01, 0xe3, 0x0d, 0xdc, 0x5f, 0x77, 0x22, 0x19, 0xf4, 0x0c, + 0xfb, 0xd9, 0x76, 0x72, 0x89, 0x9a, 0x50, 0x64, 0x51, 0xc6, 0x5f, 0x64, 0x91, 0xf1, 0xd7, 0x26, + 0x34, 0xce, 0xd8, 0x11, 0x9b, 0x3f, 0xd3, 0x27, 0x50, 0x23, 0x0c, 0xf3, 0xe5, 0x51, 0xba, 0x00, + 0x24, 0x61, 0x4c, 0x2f, 0xf2, 0x61, 0x1a, 0xd3, 0x0b, 0xd4, 0xce, 0x7a, 0xc1, 0xa6, 0xea, 0x05, + 0xab, 0xed, 0x75, 0x99, 0x78, 0xb9, 0xfc, 0x1f, 0x42, 0x05, 0x47, 0x1e, 0xe7, 0x8c, 0x64, 0xd5, + 0x5d, 0xc6, 0x91, 0xcb, 0x19, 0x41, 0x26, 0xd4, 0x70, 0x22, 0x26, 0x9e, 0x62, 0x2c, 0x29, 0xc6, + 0x17, 0x77, 0x33, 0x9a, 0xb6, 0x7c, 0xcd, 0x8a, 0xb7, 0x8a, 0xb3, 0x95, 0x1c, 0x58, 0x38, 0xf2, + 0xfc, 0x09, 0x0e, 0x02, 0x9a, 0x0e, 0xe4, 0x6d, 0xa7, 0x86, 0xa3, 0x4e, 0x0a, 0xa0, 0xff, 0x41, + 0x19, 0x47, 0x5e, 0xc4, 0x2f, 0xd5, 0x38, 0xae, 0x39, 0x25, 0x1c, 0xd9, 0xfc, 0x12, 0xed, 0x43, + 0x03, 0x47, 0xde, 0x84, 0x11, 0x9a, 0x86, 0x95, 0x4e, 0x63, 0xc0, 0x51, 0x8f, 0x11, 0xaa, 0x42, + 0x7b, 0x0e, 0x75, 0x7f, 0xca, 0x68, 0x20, 0x52, 0x83, 0x5a, 0x9a, 0xa1, 0x14, 0x52, 0x06, 0x4f, + 0x21, 0x93, 0x14, 0x3b, 0xa4, 0x29, 0x4a, 0x11, 0xb9, 0xc3, 0xb7, 0xd0, 0x24, 0x4c, 0xdd, 0xa2, + 0x17, 0xd0, 0xdf, 0x66, 0x61, 0x90, 0x0d, 0xe1, 0xed, 0x0c, 0x1d, 0x2a, 0xd0, 0x78, 0x95, 0xb5, + 0x9c, 0x32, 0x14, 0x4d, 0x5b, 0xdb, 0x40, 0x15, 0xd8, 0x74, 0x4f, 0x4d, 0xad, 0x80, 0xee, 0xc1, + 0x8e, 0x7b, 0x6a, 0x7a, 0x47, 0x66, 0xff, 0x64, 0xf4, 0xc1, 0x72, 0x3c, 0xd3, 0xd6, 0x8a, 0xc6, + 0x0b, 0x80, 0xc5, 0x25, 0xa0, 0x06, 0x54, 0xcf, 0x6c, 0xb3, 0xed, 0xd9, 0xee, 0x7b, 0x6d, 0x03, + 0x55, 0x61, 0x6b, 0x64, 0x5b, 0x43, 0xad, 0x60, 0x54, 0xa0, 0x64, 0xcd, 0x22, 0x71, 0xdd, 0xfe, + 0x7d, 0x0b, 0xca, 0xf6, 0xe1, 0xd9, 0xd0, 0x7e, 0x8d, 0x06, 0xa0, 0x1f, 0x53, 0xd1, 0xa5, 0xd1, + 0x34, 0xbc, 0xa6, 0x64, 0x65, 0x7c, 0x20, 0xb4, 0xda, 0xd0, 0xa5, 0xeb, 0xde, 0xe3, 0xcf, 0xcc, + 0x4d, 0x63, 0x03, 0xf5, 0xe0, 0x5e, 0xca, 0xf5, 0x9f, 0x99, 0x8e, 0x60, 0xf7, 0x98, 0x8a, 0x1b, + 0xbf, 0xbb, 0x7f, 0xc1, 0x33, 0x82, 0x5d, 0xf7, 0x16, 0xcf, 0xe7, 0x7c, 0xbe, 0x44, 0xf8, 0x33, + 0x34, 0x8f, 0xa9, 0x58, 0xfe, 0xa7, 0xae, 0x8b, 0x4a, 0x5f, 0xc1, 0x96, 0xac, 0x53, 0x06, 0x77, + 0x95, 0xe1, 0x4e, 0xeb, 0xbd, 0x35, 0xdc, 0xc6, 0x06, 0xea, 0x42, 0x63, 0x20, 0x7f, 0xc0, 0xe3, + 0x81, 0xab, 0x7a, 0xfd, 0x17, 0x7e, 0x33, 0xeb, 0x59, 0xce, 0xcb, 0xea, 0x0b, 0xfe, 0xc3, 0x3f, + 0x01, 0x00, 0x00, 0xff, 0xff, 0x6c, 0x92, 0x45, 0x40, 0x90, 0x0b, 0x00, 0x00, } diff --git a/proto/grpc.proto b/proto/grpc.proto index 3bbecc7..1ba1553 100644 --- a/proto/grpc.proto +++ b/proto/grpc.proto @@ -33,9 +33,10 @@ message GadgetSettings { bool use_HID_RAW = 11; bool use_UMS = 12; bool use_SERIAL = 13; - GadgetSettingsEthernet rndis_settings = 14; - GadgetSettingsEthernet cdc_ecm_settings = 15; + GadgetSettingsEthernet rndis_settings = 14; //Only applicable if RNDIS on + GadgetSettingsEthernet cdc_ecm_settings = 15; //Only applicable if CDC ECM on GadgetSettingsUMS ums_settings = 16; + EthernetInterfaceSettings ethernet_settings = 17; //only applicable if RNDIS or CDC ECM on } message GadgetSettingsEthernet { @@ -59,7 +60,8 @@ message EthernetInterfaceSettings { Mode mode = 2; string ipAddress4 = 3; string netmask4 = 4; - DHCPServerSettings dhcpServerSettings = 5; + bool enabled = 5; + DHCPServerSettings dhcpServerSettings = 6; } /* DHCP */ diff --git a/service/DHCPSrv.go b/service/DHCPSrv.go index 8732039..4316940 100644 --- a/service/DHCPSrv.go +++ b/service/DHCPSrv.go @@ -7,55 +7,11 @@ import ( "os" ) -const ( - dnsmasq_conf_head = `port=0 - listen-address=$IF_IP - dhcp-range=$IF_DHCP_RANGE,$IF_MASK,5m - dhcp-option=252,http://$IF_IP/wpad.dat - # router - dhcp-option=3,$IF_IP - # DNS - dhcp-option=6,$IF_IP - # NETBIOS NS - dhcp-option=44,$IF_IP - dhcp-option=45,$IF_IP - # routes static (route 0.0.0.1 to 127.255.255.254 through our device) - dhcp-option=121,0.0.0.0/1,$IF_IP,128.0.0.0/1,$IF_IP - # routes static (route 128.0.0.1 to 255.255.255.254 through our device) - dhcp-option=249,0.0.0.0/1,$IF_IP,128.0.0.0/1,$IF_IP - dhcp-leasefile=/tmp/dnsmasq.leases - dhcp-authoritative - log-dhcp` - -) - /* The DHCP server part relies on "dnsmasq" and thus depends on the binary Note: dnsmasq default option have to be disabled explicitly if not needed, by setting an empty value (1, 3, 6, 12, 28) */ -func DefaultDHCPConfigUSB() (settings *pb.DHCPServerSettings) { - settings = &pb.DHCPServerSettings{ - CallbackScript: "/bin/evilscript", - DoNotBindInterface: false, //only bind to given interface - ListenInterface: USB_ETHERNET_BRIDGE_NAME, - LeaseFile: "/tmp/dnsmasq_" + USB_ETHERNET_BRIDGE_NAME + ".leases", - ListenPort: 0, //No DNS, DHCP only - NotAuthoritative: false, //be authoritative - Ranges: []*pb.DHCPServerRange { - &pb.DHCPServerRange{ RangeLower:"172.16.0.2", RangeUpper: "172.16.0.3", LeaseTime: "5m"}, - &pb.DHCPServerRange{ RangeLower:"172.16.0.5", RangeUpper: "172.16.0.6", LeaseTime: "2m"}, - }, - Options: map[uint32]string { - 3: "", //Disable option: Router - 6: "", //Disable option: DNS - 252: "http://172.16.0.1/wpad.dat", - //Options 1 (Netmask), 12 (Hostname) and 28 (Broadcast Address) are still enabled - }, - } - return -} - func defaultLeaseFile(s *pb.DHCPServerSettings) (lf string) { return fmt.Sprintf("/tmp/dnsmasq_%s.leases", s.ListenInterface) //default lease file } diff --git a/service/defaults.go b/service/defaults.go new file mode 100644 index 0000000..95b3435 --- /dev/null +++ b/service/defaults.go @@ -0,0 +1,73 @@ +package service + +import ( + pb "../proto" +) + +func GetDefaultNetworkSettingsUSB() (*pb.EthernetInterfaceSettings) { + //configure 172.24.0.1/255.255.255.252 for usbeth + ifSettings := &pb.EthernetInterfaceSettings { + Enabled: false, + Name: USB_ETHERNET_BRIDGE_NAME, + IpAddress4: "172.16.0.1", + Netmask4: "255.255.255.252", + Mode: pb.EthernetInterfaceSettings_MANUAL, + DhcpServerSettings: GetDefaultDHCPConfigUSB(), + } + return ifSettings +} + +func GetDefaultDHCPConfigUSB() (settings *pb.DHCPServerSettings) { + settings = &pb.DHCPServerSettings{ + CallbackScript: "/bin/evilscript", + DoNotBindInterface: false, //only bind to given interface + ListenInterface: USB_ETHERNET_BRIDGE_NAME, + LeaseFile: "/tmp/dnsmasq_" + USB_ETHERNET_BRIDGE_NAME + ".leases", + ListenPort: 0, //No DNS, DHCP only + NotAuthoritative: false, //be authoritative + Ranges: []*pb.DHCPServerRange{ + &pb.DHCPServerRange{RangeLower: "172.16.0.2", RangeUpper: "172.16.0.2", LeaseTime: "5m"}, + //&pb.DHCPServerRange{RangeLower: "172.16.0.5", RangeUpper: "172.16.0.6", LeaseTime: "2m"}, + }, + Options: map[uint32]string{ + //Note: Options 1 (Netmask), 12 (Hostname) and 28 (Broadcast Address) are still enabled + 3: "", //Disable option: Router + 6: "", //Disable option: DNS + //252: "http://172.16.0.1/wpad.dat", + }, + } + return +} + +func GetDefaultGadgetSettings() (res pb.GadgetSettings) { + res = pb.GadgetSettings{ + Enabled: false, + Vid: "0x1d6b", + Pid: "0x1337", + Manufacturer: "MaMe82", + Product: "P4wnP1 by MaMe82", + Serial: "deadbeef1337", + Use_CDC_ECM: false, + Use_RNDIS: false, + Use_HID_KEYBOARD: false, + Use_HID_MOUSE: false, + Use_HID_RAW: false, + Use_UMS: false, + Use_SERIAL: false, + RndisSettings: &pb.GadgetSettingsEthernet{ + HostAddr: "42:63:65:12:34:56", + DevAddr: "42:63:65:56:34:12", + }, + CdcEcmSettings: &pb.GadgetSettingsEthernet{ + HostAddr: "42:63:66:12:34:56", + DevAddr: "42:63:66:56:34:12", + }, + UmsSettings: &pb.GadgetSettingsUMS{ + File:"", //we don't supply an image file, which is no problem as it could be applied later on (removable media) + Cdrom:false, //By default we don't emulate a CD drive, but a flashdrive + }, + EthernetSettings: GetDefaultNetworkSettingsUSB(), + } + + return res +} \ No newline at end of file diff --git a/service/network.go b/service/network.go index 8da5d49..040238a 100644 --- a/service/network.go +++ b/service/network.go @@ -1,7 +1,8 @@ package service import ( - "github.com/docker/libcontainer/netlink" + //"github.com/docker/libcontainer/netlink" + "../netlink" "net" "log" "io/ioutil" @@ -32,6 +33,8 @@ func IpNetFromIPv4AndNetmask(ipv4 string, netmask string) (*net.IPNet, error) { return &net.IPNet{IP: netw, Mask: mask}, nil } + + func CreateBridge(name string) (err error) { return netlink.CreateBridge(name, false) } @@ -104,8 +107,21 @@ func ConfigureInterface(settings *pb.EthernetInterfaceSettings) (err error) { ipNet, err := IpNetFromIPv4AndNetmask(settings.IpAddress4, settings.Netmask4) if err != nil { return err } + //Flush old IPs + netlink.NetworkLinkFlush(iface) //set IP + log.Printf("Setting Interface %s to IP %s\n", iface.Name, settings.IpAddress4) netlink.NetworkLinkAddIp(iface, net.ParseIP(settings.IpAddress4), ipNet) + + //ToDo: Disabling doesn't work in gadget settings, but from test.go + if settings.Enabled { + log.Printf("Setting Interface %s to UP\n", iface.Name) + err = netlink.NetworkLinkUp(iface) + } else { + log.Printf("Setting Interface %s to DOWN\n", iface.Name) + err = netlink.NetworkLinkDown(iface) + } + if err != nil { return err } } return nil diff --git a/service/usb.go b/service/usb.go index cd0ff77..46247fa 100644 --- a/service/usb.go +++ b/service/usb.go @@ -172,37 +172,7 @@ func InitDefaultGadgetSettings() error { return DeployGadgetSettings(defaultGadgetSettings) } -func GetDefaultGadgetSettings() (res pb.GadgetSettings) { - res = pb.GadgetSettings{ - Enabled: false, - Vid: "0x1d6b", - Pid: "0x1337", - Manufacturer: "MaMe82", - Product: "P4wnP1 by MaMe82", - Serial: "deadbeef1337", - Use_CDC_ECM: false, - Use_RNDIS: false, - Use_HID_KEYBOARD: false, - Use_HID_MOUSE: false, - Use_HID_RAW: false, - Use_UMS: false, - Use_SERIAL: false, - RndisSettings: &pb.GadgetSettingsEthernet{ - HostAddr: "42:63:65:12:34:56", - DevAddr: "42:63:65:56:34:12", - }, - CdcEcmSettings: &pb.GadgetSettingsEthernet{ - HostAddr: "42:63:66:12:34:56", - DevAddr: "42:63:66:56:34:12", - }, - UmsSettings: &pb.GadgetSettingsUMS{ - File:"", //we don't supply an image file, which is no problem as it could be applied later on (removable media) - Cdrom:false, //By default we don't emulate a CD drive, but a flashdrive - }, - } - return res -} //depends on `lsmod` binary func CheckLibComposite() error { @@ -622,6 +592,14 @@ func DeployGadgetSettings(settings pb.GadgetSettings) error { return err } + + //Configure bridge interface + if settings.EthernetSettings == nil { + err = errors.New("Gadget has Ethernet enabled, but no Ethernet settings provided") + log.Println(err) + return err + } + ConfigureInterface(settings.EthernetSettings) } log.Printf("... done")