diff options
Diffstat (limited to 'lib/lufa/Demos/Device/LowLevel/RNDISEthernet/Lib/DHCP.c')
| -rw-r--r-- | lib/lufa/Demos/Device/LowLevel/RNDISEthernet/Lib/DHCP.c | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/lib/lufa/Demos/Device/LowLevel/RNDISEthernet/Lib/DHCP.c b/lib/lufa/Demos/Device/LowLevel/RNDISEthernet/Lib/DHCP.c new file mode 100644 index 000000000..6f7b40af6 --- /dev/null +++ b/lib/lufa/Demos/Device/LowLevel/RNDISEthernet/Lib/DHCP.c | |||
| @@ -0,0 +1,129 @@ | |||
| 1 | /* | ||
| 2 | LUFA Library | ||
| 3 | Copyright (C) Dean Camera, 2017. | ||
| 4 | |||
| 5 | dean [at] fourwalledcubicle [dot] com | ||
| 6 | www.lufa-lib.org | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com) | ||
| 11 | |||
| 12 | Permission to use, copy, modify, distribute, and sell this | ||
| 13 | software and its documentation for any purpose is hereby granted | ||
| 14 | without fee, provided that the above copyright notice appear in | ||
| 15 | all copies and that both that the copyright notice and this | ||
| 16 | permission notice and warranty disclaimer appear in supporting | ||
| 17 | documentation, and that the name of the author not be used in | ||
| 18 | advertising or publicity pertaining to distribution of the | ||
| 19 | software without specific, written prior permission. | ||
| 20 | |||
| 21 | The author disclaims all warranties with regard to this | ||
| 22 | software, including all implied warranties of merchantability | ||
| 23 | and fitness. In no event shall the author be liable for any | ||
| 24 | special, indirect or consequential damages or any damages | ||
| 25 | whatsoever resulting from loss of use, data or profits, whether | ||
| 26 | in an action of contract, negligence or other tortious action, | ||
| 27 | arising out of or in connection with the use or performance of | ||
| 28 | this software. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** \file | ||
| 32 | * | ||
| 33 | * Dynamic Host Configuration Protocol (DHCP) packet handling routines. This protocol | ||
| 34 | * handles the automatic IP negotiation to the host, so that the host will use the provided | ||
| 35 | * IP address given to it by the device. | ||
| 36 | */ | ||
| 37 | |||
| 38 | #include "DHCP.h" | ||
| 39 | |||
| 40 | /** Processes a DHCP packet inside an Ethernet frame, and writes the appropriate response | ||
| 41 | * to the output Ethernet frame if the host is requesting or accepting an IP address. | ||
| 42 | * | ||
| 43 | * \param[in] IPHeaderInStart Pointer to the start of the incoming packet's IP header | ||
| 44 | * \param[in] DHCPHeaderInStart Pointer to the start of the incoming packet's DHCP header | ||
| 45 | * \param[out] DHCPHeaderOutStart Pointer to the start of the outgoing packet's DHCP header | ||
| 46 | * | ||
| 47 | * \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise | ||
| 48 | */ | ||
| 49 | int16_t DHCP_ProcessDHCPPacket(void* IPHeaderInStart, | ||
| 50 | void* DHCPHeaderInStart, | ||
| 51 | void* DHCPHeaderOutStart) | ||
| 52 | { | ||
| 53 | IP_Header_t* IPHeaderIN = (IP_Header_t*)IPHeaderInStart; | ||
| 54 | DHCP_Header_t* DHCPHeaderIN = (DHCP_Header_t*)DHCPHeaderInStart; | ||
| 55 | DHCP_Header_t* DHCPHeaderOUT = (DHCP_Header_t*)DHCPHeaderOutStart; | ||
| 56 | |||
| 57 | uint8_t* DHCPOptionsINStart = (uint8_t*)(DHCPHeaderInStart + sizeof(DHCP_Header_t)); | ||
| 58 | uint8_t* DHCPOptionsOUTStart = (uint8_t*)(DHCPHeaderOutStart + sizeof(DHCP_Header_t)); | ||
| 59 | |||
| 60 | DecodeDHCPHeader(DHCPHeaderInStart); | ||
| 61 | |||
| 62 | /* Zero out the response DHCP packet, as much of it is legacy and left at 0 */ | ||
| 63 | memset(DHCPHeaderOUT, 0, sizeof(DHCP_Header_t)); | ||
| 64 | |||
| 65 | /* Fill out the response DHCP packet */ | ||
| 66 | DHCPHeaderOUT->HardwareType = DHCPHeaderIN->HardwareType; | ||
| 67 | DHCPHeaderOUT->Operation = DHCP_OP_BOOTREPLY; | ||
| 68 | DHCPHeaderOUT->HardwareAddressLength = DHCPHeaderIN->HardwareAddressLength; | ||
| 69 | DHCPHeaderOUT->Hops = 0; | ||
| 70 | DHCPHeaderOUT->TransactionID = DHCPHeaderIN->TransactionID; | ||
| 71 | DHCPHeaderOUT->ElapsedSeconds = 0; | ||
| 72 | DHCPHeaderOUT->Flags = DHCPHeaderIN->Flags; | ||
| 73 | DHCPHeaderOUT->YourIP = ClientIPAddress; | ||
| 74 | memmove(&DHCPHeaderOUT->ClientHardwareAddress, &DHCPHeaderIN->ClientHardwareAddress, sizeof(MAC_Address_t)); | ||
| 75 | DHCPHeaderOUT->Cookie = SwapEndian_32(DHCP_MAGIC_COOKIE); | ||
| 76 | |||
| 77 | /* Alter the incoming IP packet header so that the corrected IP source and destinations are used - this means that | ||
| 78 | when the response IP header is generated, it will use the corrected addresses and not the null/broatcast addresses */ | ||
| 79 | IPHeaderIN->SourceAddress = ClientIPAddress; | ||
| 80 | IPHeaderIN->DestinationAddress = ServerIPAddress; | ||
| 81 | |||
| 82 | /* Process the incoming DHCP packet options */ | ||
| 83 | while (DHCPOptionsINStart[0] != DHCP_OPTION_END) | ||
| 84 | { | ||
| 85 | /* Find the Message Type DHCP option, to determine the type of DHCP packet */ | ||
| 86 | if (DHCPOptionsINStart[0] == DHCP_OPTION_MESSAGETYPE) | ||
| 87 | { | ||
| 88 | if ((DHCPOptionsINStart[2] == DHCP_MESSAGETYPE_DISCOVER) || (DHCPOptionsINStart[2] == DHCP_MESSAGETYPE_REQUEST)) | ||
| 89 | { | ||
| 90 | /* Fill out the response DHCP packet options for a DHCP OFFER or ACK response */ | ||
| 91 | |||
| 92 | *(DHCPOptionsOUTStart++) = DHCP_OPTION_MESSAGETYPE; | ||
| 93 | *(DHCPOptionsOUTStart++) = 1; | ||
| 94 | *(DHCPOptionsOUTStart++) = (DHCPOptionsINStart[2] == DHCP_MESSAGETYPE_DISCOVER) ? DHCP_MESSAGETYPE_OFFER | ||
| 95 | : DHCP_MESSAGETYPE_ACK; | ||
| 96 | |||
| 97 | *(DHCPOptionsOUTStart++) = DHCP_OPTION_SUBNETMASK; | ||
| 98 | *(DHCPOptionsOUTStart++) = sizeof(IP_Address_t); | ||
| 99 | *(DHCPOptionsOUTStart++) = 0xFF; | ||
| 100 | *(DHCPOptionsOUTStart++) = 0xFF; | ||
| 101 | *(DHCPOptionsOUTStart++) = 0xFF; | ||
| 102 | *(DHCPOptionsOUTStart++) = 0x00; | ||
| 103 | |||
| 104 | *(DHCPOptionsOUTStart++) = DHCP_OPTION_LEASETIME; | ||
| 105 | *(DHCPOptionsOUTStart++) = sizeof(uint32_t); | ||
| 106 | /* Lease Time 86400s (ONE_DAY) */ | ||
| 107 | *(DHCPOptionsOUTStart++) = 0x00; | ||
| 108 | *(DHCPOptionsOUTStart++) = 0x01; | ||
| 109 | *(DHCPOptionsOUTStart++) = 0x51; | ||
| 110 | *(DHCPOptionsOUTStart++) = 0x80; | ||
| 111 | |||
| 112 | *(DHCPOptionsOUTStart++) = DHCP_OPTION_DHCPSERVER; | ||
| 113 | *(DHCPOptionsOUTStart++) = sizeof(IP_Address_t); | ||
| 114 | memcpy(DHCPOptionsOUTStart, &ServerIPAddress, sizeof(IP_Address_t)); | ||
| 115 | DHCPOptionsOUTStart += sizeof(IP_Address_t); | ||
| 116 | |||
| 117 | *(DHCPOptionsOUTStart++) = DHCP_OPTION_END; | ||
| 118 | |||
| 119 | return (sizeof(DHCP_Header_t) + 18 + sizeof(IP_Address_t)); | ||
| 120 | } | ||
| 121 | } | ||
| 122 | |||
| 123 | /* Go to the next DHCP option - skip one byte if option is a padding byte, else skip the complete option's size */ | ||
| 124 | DHCPOptionsINStart += ((DHCPOptionsINStart[0] == DHCP_OPTION_PAD) ? 1 : (DHCPOptionsINStart[1] + 2)); | ||
| 125 | } | ||
| 126 | |||
| 127 | return NO_RESPONSE; | ||
| 128 | } | ||
| 129 | |||
