Пример #1
0
func main() {

	var err error

	// Loading of the parameters
	getParameters()

	database, err = sql.Open("sqlite3", "mysqlite_3")
	if err != nil {
		log.Fatal(err)
	}
	defer database.Close()

	initDB()

	handler := func(data []byte) {
		pkg := dhcpPacket.NewDhcpPacket()
		dhcpPacket.ParseDhcpPacket(data, pkg)
		if pkg.GetMessageType() == 1 {
			response(pkg)
		} else if pkg.GetMessageType() == 3 {
			ack(pkg)
		} else if pkg.GetMessageType() == 7 {
			release(pkg)
		}
	}

	dhcpUDP.InitListener(handler)

}
Пример #2
0
func response(request *dhcpPacket.DhcpPacket) {

	var err error

	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(request.GetXid())
	mac_request := request.GetChaddr()
	packet_response.SetChaddr(mac_request)

	var row1 sqlRow

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

	err1 := stmt.QueryRow(mac_request.String()).Scan(&row1.Id, &row1.IP, &row1.MAC, &row1.Release_date)
	if err1 != nil {
		fmt.Println("Erreur lors de la requête 1")
		fmt.Println(err1)
	}

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

	var row2 sqlRow
	err2 := stmt.QueryRow("").Scan(&row2.Id, &row2.IP, &row2.MAC, &row2.Release_date)
	if err2 != nil {
		fmt.Println("Erreur lors de la requête 2")
		fmt.Println(err2)
	}

	stmt, err = database.Prepare("SELECT * FROM IP_table WHERE ( CURRENT_TIMESTAMP > release_date )")
	if err != nil {
		log.Fatal(err)
	}

	var row3 sqlRow
	err3 := stmt.QueryRow().Scan(&row3.Id, &row3.IP, &row3.MAC, &row3.Release_date)
	if err3 != nil {
		fmt.Println("Erreur lors de la requête 3")
		fmt.Println(err3)
	}

	// We allocate the IP for 3 minutes to give the time to receive a dhcp request
	if err1 == nil {
		packet_response.SetYiaddr(row1.IP)
		_, err = database.Exec(
			"UPDATE IP_table SET release_date=datetime(CURRENT_TIMESTAMP, '+3 minutes') WHERE id = ?", row1.Id)
	} else if err2 == nil {
		packet_response.SetYiaddr(row2.IP)
		_, err = database.Exec(
			"UPDATE IP_table SET release_date=datetime(CURRENT_TIMESTAMP, '+3 minutes'), MAC = ? WHERE id = ?", mac_request.String(), row2.Id)
	} else if err3 == nil {
		packet_response.SetYiaddr(row3.IP)
		_, err = database.Exec(
			"UPDATE IP_table SET release_date=datetime(CURRENT_TIMESTAMP, '+3 minutes'), MAC = ? WHERE id = ?", mac_request.String(), row3.Id)
	} else {
		fmt.Println("All IPs are used")
		packet_response.SetMessageType(6)
		packet_response.SetYiaddr("0.0.0.0")
		packet_response.SetSiaddr("0.0.0.0")
	}
	if err != nil {
		fmt.Println("Failed to check the database")
		log.Fatal(err)
	}

	packet_response.SetMessageType(2)
	packet_response.Options.Add(255, nil)

	// Sending the packet

	raddr := net.UDPAddr{IP: net.ParseIP("255.255.255.255"), 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() == 2 {
		fmt.Println("OFFER Sent - Bytes written : ", n)
	} else {
		fmt.Println("NACK Sent - Bytes written : ", n)
	}
	conn.Close()
}
Пример #3
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()
}