func client() { ifaces, err := net.Interfaces() if err != nil { log.Printf("client: Can't enumerate interfaces? %v", err) return } addr, _, err := net.ParseCIDR("0.0.0.0/32") if err != nil { log.Printf("client: Can't parse to ip: %v", err) return } p := dhcp.RequestPacket(dhcp.Discover, ifaces[0].HardwareAddr, addr, []byte{1, 2, 3}, true, nil) fmt.Printf("client: %q\n", p) for { fmt.Printf("Try it\n") d, err := net.Dial("udp", "127.0.0.1:67") if err != nil { log.Printf("client: dial bad %v", err) } fmt.Printf("client: d is %q\n", d) ra, err := net.ResolveUDPAddr("udp", "127.0.0.1:67") if err != nil { log.Printf("client: ResolveUDPAddr failed: %v", err) return } fmt.Printf("client: ra %v\n", ra) if err := d.SetDeadline(time.Now().Add(10000 * time.Millisecond)); err != nil { log.Printf("client: Can't set deadline: %v\n", err) return } if _, err := d.Write(p); err != nil { log.Printf("client: WriteToUDP failed: %v", err) return } else { b := [512]byte{} if err := d.SetReadDeadline(time.Now().Add(10000 * time.Millisecond)); err != nil { log.Printf("client: Can't set deadline: %v\n", err) return } fmt.Printf("Client: sleep the read\n") time.Sleep(time.Second) if n, err := d.Read(b[:]); err != nil { log.Printf("client: Read from UDP failed: %v", err) continue } else { fmt.Printf("client: Data %v amt %v \n", b, n) return } } } }
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 }