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() }