Example #1
0
// ReplyPacket creates a reply packet that a Server would send to a client.
// It uses the req Packet param to copy across common/necessary fields to
// associate the reply with the request.
func informReplyPacket(req dhcp4.Packet, mt dhcp4.MessageType, serverID net.IP, options []dhcp4.Option) dhcp4.Packet {
	p := dhcp4.NewPacket(dhcp4.BootReply)
	p.SetXId(req.XId())
	p.SetHType(req.HType())
	p[2] = req.HLen() // dhcp4 library does not provide a setter
	p.SetFlags(req.Flags())
	p.SetCIAddr(req.CIAddr())
	p.SetCHAddr(req.CHAddr())
	p.AddOption(dhcp4.OptionDHCPMessageType, []byte{byte(mt)})
	p.AddOption(dhcp4.OptionServerIdentifier, []byte(serverID))
	for _, o := range options {
		p.AddOption(o.Code, o.Value)
	}
	p.PadToMinSize()
	return p
}
Example #2
0
func main() {
	if len(os.Args) != 3 {
		panic("not enough args")
	}

	intf, err := net.InterfaceByName(os.Args[1])
	if err != nil {
		panic(err)
	}

	containerID := os.Args[2]

	log.Infof("Requesting for container ID %q on interface %q", containerID, intf.Name)

	contPid := getContainerInfo(containerID)
	log.Infof("Container has PID %s", contPid)

	runtime.LockOSThread()
	f, err := os.Open(fmt.Sprintf("/proc/%s/ns/net", contPid))
	if err != nil {
		panic(err)
	}

	if _, _, err := unix.RawSyscall(unix.SYS_SETNS, f.Fd(), syscall.CLONE_NEWNET, 0); err != 0 {
		panic(err)
	}

	link, err := netlink.LinkByName("eth0")
	if err != nil {
		panic(err)
	}

	chaddr := link.Attrs().HardwareAddr

	p := dhcp.RequestPacket(dhcp.Discover, chaddr, nil, []byte{1, 2, 3, 4}, true, []dhcp.Option{})
	conn, err := net.ListenPacket("udp", ":68")
	if err != nil {
		panic(err)
	}

	ipc := ipv4.NewPacketConn(conn)
	ipc.SetControlMessage(ipv4.FlagInterface, true)
	to := &net.UDPAddr{
		IP:   net.IPv4(255, 255, 255, 255),
		Port: 67,
	}

	eth0, err := net.InterfaceByName("eth0")
	if err != nil {
		panic(err)
	}

	if _, err := ipc.WriteTo(p, &ipv4.ControlMessage{IfIndex: eth0.Index}, to); err != nil {
		panic(err)
	}

	newPacket := dhcp.NewPacket(dhcp.BootReply)

	for {
		_, cm, _, err := ipc.ReadFrom(newPacket)
		if err != nil {
			panic(err)
		}

		if cm != nil && cm.IfIndex == eth0.Index {
			log.Infof("Received reply: %q", newPacket.YIAddr().String())
			break
		}
	}

	addr, err := netlink.ParseAddr(newPacket.YIAddr().String() + "/16")
	if err != nil {
		panic(err)
	}

	log.Infof("Setting interface eth0...")

	if err := netlink.AddrAdd(link, addr); err != nil {
		panic(err)
	}
}