Ejemplo n.º 1
0
func ack(discover *dhcpPacket.DhcpPacket) {

	packet_response := dhcpPacket.NewDhcpPacket()

	// Fixed part in the body
	packet_response.SetOp(2)
	packet_response.SetCiaddr("0.0.0.0")
	packet_response.SetSiaddr(parameters.IP_server)
	packet_response.SetGiaddr("0.0.0.0")

	// Fixed part in the options
	packet_response.SetDhcpServer(parameters.IP_server)
	packet_response.SetLeaseTime(parameters.Allocation_time)
	packet_response.SetSubnetMask(parameters.Netmask)
	packet_response.SetDnsServer([]string{parameters.IP_DNS})
	packet_response.SetRouter(parameters.IP_server)

	// Specific response to the client request
	packet_response.SetXid(discover.GetXid())
	mac_request := discover.GetChaddr()
	packet_response.SetChaddr(mac_request)

	var row sqlRow

	stmt, err := database.Prepare("SELECT * FROM IP_table WHERE MAC = ?")
	if err != nil {
		fmt.Println(err)
	}

	err = stmt.QueryRow(mac_request.String()).Scan(&row.Id, &row.IP, &row.MAC, &row.Release_date)
	if err != nil {

		if err == sql.ErrNoRows {
			packet_response.SetMessageType(6)
			packet_response.SetYiaddr("0.0.0.0")
			packet_response.SetSiaddr("0.0.0.0")
		} else {
			fmt.Println("Failed to check the database")
			fmt.Println(err)
		}

	} else {
		// We allocate the IP for allocation_time
		packet_response.SetMessageType(5)
		packet_response.SetYiaddr(row.IP)

		timeModifier := "+" + strconv.Itoa(parameters.Allocation_time) + " seconds"

		_, err = database.Exec(
			"UPDATE IP_table SET release_date=datetime(CURRENT_TIMESTAMP, ?) WHERE id = ?", timeModifier, row.Id)
		if err != nil {
			fmt.Println(err)
		}
	}

	packet_response.Options.Add(255, nil)

	// Sending the packet

	destIp := "255.255.255.255"

	if discover.GetCiaddr().String() != "0.0.0.0" {
		destIp = discover.GetCiaddr().String()
	}

	raddr := net.UDPAddr{IP: net.ParseIP(destIp), Port: 68}
	laddr, err := net.ResolveUDPAddr("udp", parameters.IP_server+":"+strconv.Itoa(parameters.OutPort))

	conn, err := net.DialUDP("udp", laddr, &raddr)
	if err != nil {
		fmt.Print(err)
	}

	n, err := conn.Write(packet_response.ToBytes())
	if err != nil {
		fmt.Println(err)
	}

	if packet_response.GetMessageType() == 5 {
		fmt.Println("ACK Sent - Bytes written : ", n)
	} else {
		fmt.Println("NACK Sent - Bytes written : ", n)
	}
	conn.Close()
}