Daiki Kato / DhcpServer_mbed-os

Fork of DhcpServer by Daiki Kato

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DhcpServer.cpp Source File

DhcpServer.cpp

00001 #include "mbed.h"
00002 #include "rtos.h"
00003 #include "TCPSocket.h"
00004 #include "TCPServer.h"
00005 #include "SocketAddress.h"
00006 #include "UDPSocket.h"
00007 #include "DhcpServer.h"
00008 
00009  /* DHCP message item offsets and length */
00010 #define DHCP_SNAME_LEN    64U
00011 
00012 /* DHCP message types */
00013 #define DHCP_DISCOVER               1
00014 #define DHCP_OFFER                  2
00015 #define DHCP_REQUEST                3
00016 #define DHCP_DECLINE                4
00017 #define DHCP_ACK                    5
00018 #define DHCP_NAK                    6
00019 #define DHCP_RELEASE                7
00020 #define DHCP_INFORM                 8
00021 
00022 /* BootP options */
00023 #define DHCP_OPTION_SUBNET_MASK     1 /* RFC 2132 3.3 */
00024 #define DHCP_OPTION_ROUTER          3
00025 #define DHCP_OPTION_DNS_SERVER      6
00026 
00027 /* DHCP options */
00028 #define DHCP_OPTION_LEASE_TIME      51 /* RFC 2132 9.2, time in seconds, in 4 bytes */
00029 
00030 #define DHCP_OPTION_MESSAGE_TYPE    53 /* RFC 2132 9.6, important for DHCP */
00031 #define DHCP_OPTION_MESSAGE_TYPE_LEN 1
00032 
00033 #define DHCP_OPTION_SERVER_ID       54 /* RFC 2132 9.7, server IP address */
00034 
00035 
00036 #define IP_ADDER_START (10)
00037 
00038 #define OFS_XID        (4)
00039 #define OFS_YIADDR     (16)
00040 #define OFS_SIADDR     (20)
00041 #define OFS_CHADDR     (28)
00042 #define OFS_SNAME      (44)
00043 #define OFS_COOKIE     (236)
00044 #define OFS_OPTIONS    (240)
00045 
00046 void DhcpServer::dhcp_process(void) {
00047     SocketAddress client;
00048     int cnt;
00049     int tbl_index;
00050     int option;
00051     nsapi_addr_t addr;
00052     const char mac_no_use[6] = {0, 0, 0, 0, 0, 0};
00053 
00054     dhcp_server.bind(67);
00055     option = 1;
00056     dhcp_server.setsockopt(0xfff, 0x0020, &option, sizeof(option));
00057 
00058     while (true) {
00059         int n = dhcp_server.recvfrom(&client, receivebuff, 500);
00060         if (n > 0) {
00061             addr.version = NSAPI_IPv4;
00062             addr.bytes[0] = 255;
00063             addr.bytes[1] = 255;
00064             addr.bytes[2] = 255;
00065             addr.bytes[3] = 255;
00066             client.set_addr(addr);
00067             client.set_port(68);
00068 
00069             sendbuff[OFS_XID + 0]    = receivebuff[OFS_XID + 0];
00070             sendbuff[OFS_XID + 1]    = receivebuff[OFS_XID + 1];
00071             sendbuff[OFS_XID + 2]    = receivebuff[OFS_XID + 2];
00072             sendbuff[OFS_XID + 3]    = receivebuff[OFS_XID + 3];
00073 
00074             tbl_index = -1;
00075             for (cnt = 0; cnt < CONNECT_NUM; cnt++) {
00076                 if (memcmp(&receivebuff[OFS_CHADDR], chaddr_tbl[cnt], 6) == 0) {
00077                     tbl_index = cnt;
00078                     break;
00079                 }
00080             }
00081             if (tbl_index == -1) {
00082                 sendbuff[OFS_YIADDR + 0] = 0;
00083                 sendbuff[OFS_YIADDR + 1] = 0;
00084                 sendbuff[OFS_YIADDR + 2] = 0;
00085                 sendbuff[OFS_YIADDR + 3] = 0;
00086             } else {
00087                 sendbuff[OFS_YIADDR + 0] = sendbuff[OFS_SIADDR + 0];
00088                 sendbuff[OFS_YIADDR + 1] = sendbuff[OFS_SIADDR + 1];
00089                 sendbuff[OFS_YIADDR + 2] = sendbuff[OFS_SIADDR + 2];
00090                 sendbuff[OFS_YIADDR + 3] = IP_ADDER_START + tbl_index;
00091             }
00092 
00093             sendbuff[OFS_CHADDR + 0] = receivebuff[OFS_CHADDR + 0];
00094             sendbuff[OFS_CHADDR + 1] = receivebuff[OFS_CHADDR + 1];
00095             sendbuff[OFS_CHADDR + 2] = receivebuff[OFS_CHADDR + 2];
00096             sendbuff[OFS_CHADDR + 3] = receivebuff[OFS_CHADDR + 3];
00097             sendbuff[OFS_CHADDR + 4] = receivebuff[OFS_CHADDR + 4];
00098             sendbuff[OFS_CHADDR + 5] = receivebuff[OFS_CHADDR + 5];
00099 
00100             if (receivebuff[OFS_OPTIONS + 2] == DHCP_DISCOVER) {
00101                 sendbuff[OFS_OPTIONS + 2]  = DHCP_OFFER;
00102                 if (tbl_index == -1) {
00103                     for (cnt = 0; cnt < CONNECT_NUM; cnt++) {
00104                         if (memcmp( chaddr_tbl[cnt], mac_no_use, 6) == 0) {
00105                             tbl_index = cnt;
00106                             break;
00107                         }
00108                     }
00109                 }
00110                 if (tbl_index != -1) {
00111                     chaddr_tbl[tbl_index][0]  = receivebuff[OFS_CHADDR + 0];
00112                     chaddr_tbl[tbl_index][1]  = receivebuff[OFS_CHADDR + 1];
00113                     chaddr_tbl[tbl_index][2]  = receivebuff[OFS_CHADDR + 2];
00114                     chaddr_tbl[tbl_index][3]  = receivebuff[OFS_CHADDR + 3];
00115                     chaddr_tbl[tbl_index][4]  = receivebuff[OFS_CHADDR + 4];
00116                     chaddr_tbl[tbl_index][5]  = receivebuff[OFS_CHADDR + 5];
00117                     sendbuff[OFS_YIADDR + 0] = sendbuff[OFS_SIADDR + 0];
00118                     sendbuff[OFS_YIADDR + 1] = sendbuff[OFS_SIADDR + 1];
00119                     sendbuff[OFS_YIADDR + 2] = sendbuff[OFS_SIADDR + 2];
00120                     sendbuff[OFS_YIADDR + 3] = IP_ADDER_START + tbl_index;
00121                 }
00122                 dhcp_server.sendto(client, sendbuff, 300);
00123             } else if (receivebuff[OFS_OPTIONS + 2] == DHCP_REQUEST) {
00124                 if (tbl_index != -1) {
00125                     sendbuff[OFS_OPTIONS + 2]  = DHCP_ACK;
00126                 } else {
00127                     sendbuff[OFS_OPTIONS + 2]  = DHCP_NAK;
00128                 }
00129                 dhcp_server.sendto(client, sendbuff, 300);
00130             } else if (receivebuff[OFS_OPTIONS + 2] == DHCP_RELEASE) {
00131                 if (tbl_index != -1) {
00132                     memset(chaddr_tbl[tbl_index], 0, 6);
00133                 }
00134             } else {
00135                 // do nothing
00136             }
00137         }
00138     }
00139 }
00140 
00141 DhcpServer::DhcpServer(NetworkInterface *net, const char * name) :
00142  dhcp_server(net), dhcpThread(osPriorityNormal, (1024 * 8)) {
00143     uint32_t i;
00144     uint32_t len;
00145     uint32_t ofs;
00146 
00147     receivebuff = new char[500];
00148     sendbuff = new char[300];
00149     memset(sendbuff, 0, 300);
00150     memset(chaddr_tbl, 0, sizeof(chaddr_tbl));
00151 
00152     sscanf(net->get_ip_address(), "%d.%d.%d.%d", (int *)&sendbuff[OFS_SIADDR + 0], (int *)&sendbuff[OFS_SIADDR + 1],
00153      (int *)&sendbuff[OFS_SIADDR + 2], (int *)&sendbuff[OFS_SIADDR + 3]);
00154 
00155     len = strlen(name);
00156     for (i = 0; (i < len) && (i < DHCP_SNAME_LEN); i++) {
00157         sendbuff[OFS_SNAME + i] = name[i];
00158     }
00159 
00160     sendbuff[0] = 0x02;
00161     sendbuff[1] = 0x01;
00162     sendbuff[2] = 0x06;
00163     sendbuff[3] = 0x00;
00164 
00165     sendbuff[OFS_COOKIE + 0] = 0x63;
00166     sendbuff[OFS_COOKIE + 1] = 0x82;
00167     sendbuff[OFS_COOKIE + 2] = 0x53;
00168     sendbuff[OFS_COOKIE + 3] = 0x63;
00169 
00170     ofs = OFS_OPTIONS;
00171     sendbuff[ofs++] = DHCP_OPTION_MESSAGE_TYPE;
00172     sendbuff[ofs++] = DHCP_OPTION_MESSAGE_TYPE_LEN;
00173     sendbuff[ofs++] = 0;
00174 
00175     sendbuff[ofs++] = DHCP_OPTION_SERVER_ID;
00176     sendbuff[ofs++] = 0x04;
00177     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 0];
00178     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 1];
00179     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 2];
00180     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 3];
00181 
00182     sendbuff[ofs++] = DHCP_OPTION_LEASE_TIME;
00183     sendbuff[ofs++] = 0x04;
00184     sendbuff[ofs++] = 0x00;
00185     sendbuff[ofs++] = 0x01;
00186     sendbuff[ofs++] = 0x4e;
00187     sendbuff[ofs++] = 0x20;
00188 
00189     sendbuff[ofs++] = DHCP_OPTION_SUBNET_MASK;
00190     sendbuff[ofs++] = 0x04;
00191     sendbuff[ofs++] = 0xff;
00192     sendbuff[ofs++] = 0xff;
00193     sendbuff[ofs++] = 0xff;
00194     sendbuff[ofs++] = 0xf0;
00195 
00196     sendbuff[ofs++] = DHCP_OPTION_ROUTER;
00197     sendbuff[ofs++] = 0x04;
00198     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 0];
00199     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 1];
00200     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 2];
00201     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 3];
00202 
00203     sendbuff[ofs++] = DHCP_OPTION_DNS_SERVER;
00204     sendbuff[ofs++] = 0x04;
00205     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 0];
00206     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 1];
00207     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 2];
00208     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 3];
00209 
00210     sendbuff[ofs++] = 0xff;
00211 
00212     dhcpThread.start(callback(this, &DhcpServer::dhcp_process));
00213 }
00214 
00215 DhcpServer::~DhcpServer() {
00216     delete [] receivebuff;
00217     delete [] sendbuff;
00218 }