func (typ TypeListUint32) GetListUint32() []uint32 { raw := typ.rawOpt.GetValue() listUint32 := make([]uint32, len(raw)/LEN_OPT_U_INT32) for i := range listUint32 { listUint32[i] = util.Convert4byteToUint32(raw[i*LEN_OPT_U_INT32 : (i+1)*LEN_OPT_U_INT32]) } return listUint32 }
func (this *Option121ClasslessStaticRoute) Parse(rawOpt RawOption) error { this.rawOpt = rawOpt length := int(this.rawOpt.GetLength()) if length < HEADER_LEN_OPT_121 { return errors.New(fmt.Sprintf("Option 121 is malformed : has to be greater than 5 bytes [actual: %d]", length)) } idx := 0 buf := make([]byte, 4) for idx < length { if this.rawOpt.GetValue()[idx] > MAX_CIDR { return errors.New(fmt.Sprintf("Option 121 malformed for route #%d, [expected CIDR mask lower than : %d] [actual : %d]", len(this.Routes), MAX_CIDR+1, this.rawOpt.GetValue()[idx])) } significantOctets := significantBytes(this.rawOpt.GetValue()[idx]) if idx+significantOctets+5 > length { return errors.New(fmt.Sprintf("Option 121 not enough room for route #%d, [expected : %d] [actual : %d]", len(this.Routes), significantOctets+5, length-idx)) } curRoute := new(Route) // get cidr curRoute.Mask = this.rawOpt.GetValue()[idx] // get dest copy(buf, this.rawOpt.GetValue()[idx+1:idx+significantOctets+1]) curRoute.Dest = util.Convert4byteToUint32(buf) // get gw curRoute.Gw = util.Convert4byteToUint32(this.rawOpt.GetValue()[idx+significantOctets+1 : idx+significantOctets+5]) this.Routes = append(this.Routes, *curRoute) idx += significantOctets + 5 for i := range buf { buf[i] = 0 } } return nil }
func (this *Option82_9VendorSpecificInformation) Parse(opt RawOption) error { this.rawOpt = opt this.vendorSpecInfo = make([]VendorSpecificInformation, 0, 2) var length int value := opt.GetValue() for i := 0; i < len(value); { if i+5 > len(value) { return dherrors.Opt82_9IsMalformed } curVendorSpecInfo := new(VendorSpecificInformation) curVendorSpecInfo.EnterpriseNumber = util.Convert4byteToUint32(value[i : i+4]) i += 4 length = int(value[i]) i++ if i+length > len(value) { return dherrors.Opt82_9IsMalformed } curVendorSpecInfo.Data = value[i : i+length] i += length this.vendorSpecInfo = append(this.vendorSpecInfo, *curVendorSpecInfo) } return nil }
func (_ requestRebindState) do(ctx *dhcpContext) iState { ipAddr := ctx.IpAddr.Load().(net.IP) // Set up all the layers' fields we can. eth := &layers.Ethernet{ SrcMAC: ctx.MacAddr, DstMAC: arp.HwAddrBcast, EthernetType: layers.EthernetTypeIPv4, } ipv4 := &layers.IPv4{ Version: 4, TTL: 255, Protocol: layers.IPProtocolUDP, SrcIP: net.IPv4zero, DstIP: net.IPv4bcast, } udp := &layers.UDP{ SrcPort: network.Bootpc, DstPort: network.Bootps, } udp.SetNetworkLayerForChecksum(ipv4) buf := network.GetBuffer() defer network.ReleaseBuffer(buf) request := new(dhcpv4.DhcpPacket) request.ConstructWithPreAllocatedBuffer(buf, option.DHCPREQUEST) request.SetXid(ctx.xid[:]) request.SetMacAddr(ctx.MacAddr) opt50 := new(option.Option50RequestedIpAddress) opt50.Construct(util.Convert4byteToUint32(ipAddr)) request.AddOption(opt50) opt61 := new(option.Option61ClientIdentifier) opt61.Construct(byte(1), ctx.MacAddr) request.AddOption(opt61) if DhcRelay { request.SetGiAddr(ctx.giaddr) request.AddOption(generateOption82(ctx.MacAddr)) } if Option90 { request.AddOption(generateOption90(ctx.login)) } bootp := &layer.PayloadLayer{ Contents: request.Raw, } for { // send request for err := network.SentPacket(eth, ipv4, udp, bootp); err != nil; { log.Println(ctx.MacAddr, "REBIND: error sending request", err) time.Sleep(2 * time.Second) } var ( payload []byte timeout time.Duration deadline = time.Now().Add(2 * time.Second) ) for { timeout = deadline.Sub(time.Now()) select { case <-time.After(timeout): log.Println(ctx.MacAddr, "REBIND: timeout") return timeoutRebindState{} case payload = <-ctx.dhcpIn: dp, err := dhcpv4.Parse(payload) if err != nil { // it is not DHCP packet... continue } if !bytes.Equal(ctx.xid[:], dp.GetXid()) { // bug of DHCP Server ? log.Println(ctx.MacAddr, fmt.Sprintf("REBIND: unexpected xid [Expected: 0x%v] [Actual: 0x%v]", hex.EncodeToString(ctx.xid[:]), hex.EncodeToString(dp.GetXid()))) continue } if msgType, err := dp.GetTypeMessage(); err == nil { switch msgType { case option.DHCPACK: ctx.t0, ctx.t1, ctx.t2 = extractAllLeaseTime(dp) return sleepState{} case option.DHCPNAK: log.Println(ctx.MacAddr, "REBIND: receive NAK") return discoverState{} default: log.Println(ctx.MacAddr, fmt.Sprintf("REBIND: unexpected message [Excpected: %s] [Actual: %s]", option.DHCPACK, msgType)) continue } } else { log.Println(ctx.MacAddr, "REBIND: option 53 is missing") continue } } } } }
func (dp DhcpPacket) GetGiAddr() uint32 { return util.Convert4byteToUint32(dp.Raw[24:28]) }
func (dp DhcpPacket) GetNextServerIp() uint32 { return util.Convert4byteToUint32(dp.Raw[20:24]) }
func (dp DhcpPacket) GetYourIp() uint32 { return util.Convert4byteToUint32(dp.Raw[16:20]) }
func (dp DhcpPacket) GetClientIp() uint32 { return util.Convert4byteToUint32(dp.Raw[12:16]) }
func (tuint32 TypeUint32) GetUint32() uint32 { return util.Convert4byteToUint32(tuint32.GetValue()) }