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
				}
			}
		}
	}
}
示例#5
0
func (dp DhcpPacket) GetGiAddr() uint32 {
	return util.Convert4byteToUint32(dp.Raw[24:28])
}
示例#6
0
func (dp DhcpPacket) GetNextServerIp() uint32 {
	return util.Convert4byteToUint32(dp.Raw[20:24])
}
示例#7
0
func (dp DhcpPacket) GetYourIp() uint32 {
	return util.Convert4byteToUint32(dp.Raw[16:20])
}
示例#8
0
func (dp DhcpPacket) GetClientIp() uint32 {
	return util.Convert4byteToUint32(dp.Raw[12:16])
}
func (tuint32 TypeUint32) GetUint32() uint32 {
	return util.Convert4byteToUint32(tuint32.GetValue())
}