sample

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 "lwip/netif.h"
00004 #include "TCPSocketConnection.h"
00005 #include "TCPSocketServer.h"
00006 #include "Endpoint.h"
00007 #include "UDPSocket.h"
00008 #include "dhcp.h"
00009 #include "DhcpServer.h"
00010 
00011 #define CONNECT_NUM    (5)
00012 #define IP_ADDER_START (10)
00013 
00014 #define OFS_XID        (4)
00015 #define OFS_YIADDR     (16)
00016 #define OFS_SIADDR     (20)
00017 #define OFS_CHADDR     (28)
00018 #define OFS_SNAME      (44)
00019 #define OFS_COOKIE     (236)
00020 #define OFS_OPTIONS    (240)
00021 
00022 static char receivebuff[500];
00023 static char sendbuff[300] = {0};
00024 static UDPSocket dhcp_server;
00025 static Thread * dhcpThread = NULL;
00026 static char chaddr_tbl[CONNECT_NUM][6] = {0};
00027 static const char mac_no_use[6] = {0, 0, 0, 0, 0, 0};
00028 
00029 
00030 static void dhcp_task_static(void const *argument) {
00031     Endpoint client;
00032     int cnt;
00033     int tbl_index;
00034 
00035     dhcp_server.bind(67);
00036     dhcp_server.set_broadcasting(true);
00037 
00038     while (true) {
00039         int n = dhcp_server.receiveFrom(client, receivebuff, sizeof(receivebuff));
00040         if (n > 0) {
00041             client.set_address("255.255.255.255", 68);
00042 
00043             sendbuff[OFS_XID + 0]    = receivebuff[OFS_XID + 0];
00044             sendbuff[OFS_XID + 1]    = receivebuff[OFS_XID + 1];
00045             sendbuff[OFS_XID + 2]    = receivebuff[OFS_XID + 2];
00046             sendbuff[OFS_XID + 3]    = receivebuff[OFS_XID + 3];
00047 
00048             tbl_index = -1;
00049             for (cnt = 0; cnt < CONNECT_NUM; cnt++) {
00050                 if (memcmp(&receivebuff[OFS_CHADDR], chaddr_tbl[cnt], 6) == 0) {
00051                     tbl_index = cnt;
00052                     break;
00053                 }
00054             }
00055             if (tbl_index == -1) {
00056                 sendbuff[OFS_YIADDR + 0] = 0;
00057                 sendbuff[OFS_YIADDR + 1] = 0;
00058                 sendbuff[OFS_YIADDR + 2] = 0;
00059                 sendbuff[OFS_YIADDR + 3] = 0;
00060             } else {
00061                 sendbuff[OFS_YIADDR + 0] = sendbuff[OFS_SIADDR + 0];
00062                 sendbuff[OFS_YIADDR + 1] = sendbuff[OFS_SIADDR + 1];
00063                 sendbuff[OFS_YIADDR + 2] = sendbuff[OFS_SIADDR + 2];
00064                 sendbuff[OFS_YIADDR + 3] = IP_ADDER_START + tbl_index;
00065             }
00066 
00067             sendbuff[OFS_CHADDR + 0] = receivebuff[OFS_CHADDR + 0];
00068             sendbuff[OFS_CHADDR + 1] = receivebuff[OFS_CHADDR + 1];
00069             sendbuff[OFS_CHADDR + 2] = receivebuff[OFS_CHADDR + 2];
00070             sendbuff[OFS_CHADDR + 3] = receivebuff[OFS_CHADDR + 3];
00071             sendbuff[OFS_CHADDR + 4] = receivebuff[OFS_CHADDR + 4];
00072             sendbuff[OFS_CHADDR + 5] = receivebuff[OFS_CHADDR + 5];
00073 
00074             if (receivebuff[OFS_OPTIONS + 2] == DHCP_DISCOVER) {
00075                 sendbuff[OFS_OPTIONS + 2]  = DHCP_OFFER;
00076                 if (tbl_index == -1) {
00077                     for (cnt = 0; cnt < CONNECT_NUM; cnt++) {
00078                         if (memcmp( chaddr_tbl[cnt], mac_no_use, 6) == 0) {
00079                             tbl_index = cnt;
00080                             break;
00081                         }
00082                     }
00083                 }
00084                 if (tbl_index != -1) {
00085                     chaddr_tbl[tbl_index][0]  = receivebuff[OFS_CHADDR + 0];
00086                     chaddr_tbl[tbl_index][1]  = receivebuff[OFS_CHADDR + 1];
00087                     chaddr_tbl[tbl_index][2]  = receivebuff[OFS_CHADDR + 2];
00088                     chaddr_tbl[tbl_index][3]  = receivebuff[OFS_CHADDR + 3];
00089                     chaddr_tbl[tbl_index][4]  = receivebuff[OFS_CHADDR + 4];
00090                     chaddr_tbl[tbl_index][5]  = receivebuff[OFS_CHADDR + 5];
00091                     sendbuff[OFS_YIADDR + 0] = sendbuff[OFS_SIADDR + 0];
00092                     sendbuff[OFS_YIADDR + 1] = sendbuff[OFS_SIADDR + 1];
00093                     sendbuff[OFS_YIADDR + 2] = sendbuff[OFS_SIADDR + 2];
00094                     sendbuff[OFS_YIADDR + 3] = IP_ADDER_START + tbl_index;
00095                 }
00096                 dhcp_server.sendTo(client, sendbuff, 300);
00097             } else if (receivebuff[OFS_OPTIONS + 2] == DHCP_REQUEST) {
00098                 if (tbl_index != -1) {
00099                     sendbuff[OFS_OPTIONS + 2]  = DHCP_ACK;
00100                 } else {
00101                     sendbuff[OFS_OPTIONS + 2]  = DHCP_NAK;
00102                 }
00103                 dhcp_server.sendTo(client, sendbuff, 300);
00104             } else if (receivebuff[OFS_OPTIONS + 2] == DHCP_RELEASE) {
00105                 if (tbl_index != -1) {
00106                     memset(chaddr_tbl[tbl_index], 0, 6);
00107                 }
00108             } else {
00109                 // do nothing
00110             }
00111         }
00112     }
00113 }
00114 
00115 DhcpServer::DhcpServer(char * name, char * ipadder) {
00116     int i;
00117     int len;
00118     int ofs;
00119 
00120     sscanf(ipadder, "%d.%d.%d.%d", (int *)&sendbuff[OFS_SIADDR + 0], (int *)&sendbuff[OFS_SIADDR + 1],
00121      (int *)&sendbuff[OFS_SIADDR + 2], (int *)&sendbuff[OFS_SIADDR + 3]);
00122 
00123     len = strlen(name);
00124     for (i = 0; (i < len) && (i < DHCP_SNAME_LEN); i++) {
00125         sendbuff[OFS_SNAME + i] = name[i];
00126     }
00127 
00128     sendbuff[0] = 0x02;
00129     sendbuff[1] = 0x01;
00130     sendbuff[2] = 0x06;
00131     sendbuff[3] = 0x00;
00132 
00133     sendbuff[OFS_COOKIE + 0] = 0x63;
00134     sendbuff[OFS_COOKIE + 1] = 0x82;
00135     sendbuff[OFS_COOKIE + 2] = 0x53;
00136     sendbuff[OFS_COOKIE + 3] = 0x63;
00137 
00138     ofs = OFS_OPTIONS;
00139     sendbuff[ofs++] = DHCP_OPTION_MESSAGE_TYPE;
00140     sendbuff[ofs++] = DHCP_OPTION_MESSAGE_TYPE_LEN;
00141     sendbuff[ofs++] = 0;
00142 
00143     sendbuff[ofs++] = DHCP_OPTION_SERVER_ID;
00144     sendbuff[ofs++] = 0x04;
00145     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 0];
00146     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 1];
00147     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 2];
00148     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 3];
00149 
00150     sendbuff[ofs++] = DHCP_OPTION_LEASE_TIME;
00151     sendbuff[ofs++] = 0x04;
00152     sendbuff[ofs++] = 0x00;
00153     sendbuff[ofs++] = 0x01;
00154     sendbuff[ofs++] = 0x4e;
00155     sendbuff[ofs++] = 0x20;
00156 
00157     sendbuff[ofs++] = DHCP_OPTION_SUBNET_MASK;
00158     sendbuff[ofs++] = 0x04;
00159     sendbuff[ofs++] = 0xff;
00160     sendbuff[ofs++] = 0xff;
00161     sendbuff[ofs++] = 0xff;
00162     sendbuff[ofs++] = 0xf0;
00163 
00164     sendbuff[ofs++] = DHCP_OPTION_ROUTER;
00165     sendbuff[ofs++] = 0x04;
00166     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 0];
00167     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 1];
00168     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 2];
00169     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 3];
00170 
00171     sendbuff[ofs++] = DHCP_OPTION_DNS_SERVER;
00172     sendbuff[ofs++] = 0x04;
00173     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 0];
00174     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 1];
00175     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 2];
00176     sendbuff[ofs++] = sendbuff[OFS_SIADDR + 3];
00177 
00178     sendbuff[ofs++] = 0xff;
00179 
00180     if (dhcpThread == NULL) {
00181         dhcpThread = new Thread(&dhcp_task_static, NULL, osPriorityNormal, (1024 * 8));
00182     }
00183 }
00184 
00185 DhcpServer::~DhcpServer() {
00186     if (dhcpThread != NULL) {
00187         delete dhcpThread;
00188     }
00189 }