func linkset() { iface := dev() cursor++ whatIWant = "up|down" switch arg[cursor] { case "up": if err := netlink.NetworkLinkUp(iface); err != nil { log.Fatalf("%v can't make it up: %v", iface, err) } case "down": if err := netlink.NetworkLinkDown(iface); err != nil { log.Fatalf("%v can't make it down: %v", iface, err) } default: usage() } }
func one(i net.Interface, r chan *dhcpInfo) { // the link has to be uppable if err := netlink.NetworkLinkUp(&i); err != nil { log.Printf("%v can't make it up: %v", i, err) return } addr, _, err := net.ParseCIDR("0.0.0.0/32") if err != nil { log.Printf("client: Can't parse to ip: %v", err) r <- nil return } // possibly bogus packet created. I think they are not creating an IP header. p := dhcp.RequestPacket(dhcp.Discover, i.HardwareAddr, addr, []byte{1, 2, 3}, false, nil) fmt.Printf("client: len %d\n", len(p)) u := &EtherIPUDPHeader{ Version: 4, IHL: 5, DPort: 67, SPort: 68, TotalLength: uint16(len(p)) + 20, Length: uint16(len(p)), DIP: 0xffffffff, Protocol: syscall.IPPROTO_UDP, TTL: 64, } raw := u.Marshal(p) /* goddamn. if only this had worked. s, err := syscall.LsfSocket(i.Index, syscall.ETH_P_IP) */ // yegads, the socket interface sucks so hard for over 30 years now ... // htons for a LOCAL RESOURCE? Riiiiiight. // How I miss Plan 9 s, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_DGRAM, 0x8) //syscall.ETH_P_IP) if err != nil { fmt.Printf("lsfsocket: got %v\n", err) r <- nil return } var lsall syscall.SockaddrLinklayer pp := (*[2]byte)(unsafe.Pointer(&lsall.Protocol)) pp[0] = 8 pp[1] = 0 lsall.Ifindex = i.Index lsall.Halen = 6 lsall.Addr = [8]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} if err = syscall.Bind(s, &lsall); err != nil { fmt.Printf("lsfsocket: bind got %v\n", err) r <- nil return } // we don't set family; Sendto does. bcast := &syscall.SockaddrLinklayer{ Protocol: 0x8, //syscall.ETH_P_IP, Ifindex: i.Index, Halen: 6, Addr: [8]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, } log.Printf("bcast is %v", bcast) for tries := 0; tries < 1; tries++ { fmt.Printf("Try it\n") err = syscall.Sendto(s, raw, 0, bcast) if err != nil { log.Printf("client: WriteToUDP failed: %v", err) r <- nil return } //log.Printf("wrote it; %v bytes", n) fmt.Printf("Client: sleep the read\n") time.Sleep(time.Second) b := [1024]byte{} for { n, sa, err := syscall.Recvfrom(s, b[:], 0) if err != nil { log.Printf("client: %v\n", err) r <- nil return } if n < 240 { continue } fmt.Printf("client: sa %v Data %v amt %v \n", sa, len(b[28:]), n) r <- &dhcpInfo{&i, dhcp.Packet(b[28:])} break } } close(r) //r <- nil }