sample

Fork of DhcpServer by Daiki Kato

Committer:
dkato
Date:
Wed Apr 06 03:11:10 2016 +0000
Revision:
1:14ee6da645a9
Parent:
0:1c2747611cab
Add documents

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dkato 0:1c2747611cab 1 #include "mbed.h"
dkato 0:1c2747611cab 2 #include "rtos.h"
dkato 0:1c2747611cab 3 #include "lwip/netif.h"
dkato 0:1c2747611cab 4 #include "TCPSocketConnection.h"
dkato 0:1c2747611cab 5 #include "TCPSocketServer.h"
dkato 0:1c2747611cab 6 #include "Endpoint.h"
dkato 0:1c2747611cab 7 #include "UDPSocket.h"
dkato 0:1c2747611cab 8 #include "dhcp.h"
dkato 0:1c2747611cab 9 #include "DhcpServer.h"
dkato 0:1c2747611cab 10
dkato 0:1c2747611cab 11 #define CONNECT_NUM (5)
dkato 0:1c2747611cab 12 #define IP_ADDER_START (10)
dkato 0:1c2747611cab 13
dkato 0:1c2747611cab 14 #define OFS_XID (4)
dkato 0:1c2747611cab 15 #define OFS_YIADDR (16)
dkato 0:1c2747611cab 16 #define OFS_SIADDR (20)
dkato 0:1c2747611cab 17 #define OFS_CHADDR (28)
dkato 0:1c2747611cab 18 #define OFS_SNAME (44)
dkato 0:1c2747611cab 19 #define OFS_COOKIE (236)
dkato 0:1c2747611cab 20 #define OFS_OPTIONS (240)
dkato 0:1c2747611cab 21
dkato 0:1c2747611cab 22 static char receivebuff[500];
dkato 0:1c2747611cab 23 static char sendbuff[300] = {0};
dkato 0:1c2747611cab 24 static UDPSocket dhcp_server;
dkato 0:1c2747611cab 25 static Thread * dhcpThread = NULL;
dkato 0:1c2747611cab 26 static char chaddr_tbl[CONNECT_NUM][6] = {0};
dkato 0:1c2747611cab 27 static const char mac_no_use[6] = {0, 0, 0, 0, 0, 0};
dkato 0:1c2747611cab 28
dkato 0:1c2747611cab 29
dkato 0:1c2747611cab 30 static void dhcp_task_static(void const *argument) {
dkato 0:1c2747611cab 31 Endpoint client;
dkato 0:1c2747611cab 32 int cnt;
dkato 0:1c2747611cab 33 int tbl_index;
dkato 0:1c2747611cab 34
dkato 0:1c2747611cab 35 dhcp_server.bind(67);
dkato 0:1c2747611cab 36 dhcp_server.set_broadcasting(true);
dkato 0:1c2747611cab 37
dkato 0:1c2747611cab 38 while (true) {
dkato 0:1c2747611cab 39 int n = dhcp_server.receiveFrom(client, receivebuff, sizeof(receivebuff));
dkato 0:1c2747611cab 40 if (n > 0) {
dkato 0:1c2747611cab 41 client.set_address("255.255.255.255", 68);
dkato 0:1c2747611cab 42
dkato 0:1c2747611cab 43 sendbuff[OFS_XID + 0] = receivebuff[OFS_XID + 0];
dkato 0:1c2747611cab 44 sendbuff[OFS_XID + 1] = receivebuff[OFS_XID + 1];
dkato 0:1c2747611cab 45 sendbuff[OFS_XID + 2] = receivebuff[OFS_XID + 2];
dkato 0:1c2747611cab 46 sendbuff[OFS_XID + 3] = receivebuff[OFS_XID + 3];
dkato 0:1c2747611cab 47
dkato 0:1c2747611cab 48 tbl_index = -1;
dkato 0:1c2747611cab 49 for (cnt = 0; cnt < CONNECT_NUM; cnt++) {
dkato 0:1c2747611cab 50 if (memcmp(&receivebuff[OFS_CHADDR], chaddr_tbl[cnt], 6) == 0) {
dkato 0:1c2747611cab 51 tbl_index = cnt;
dkato 0:1c2747611cab 52 break;
dkato 0:1c2747611cab 53 }
dkato 0:1c2747611cab 54 }
dkato 0:1c2747611cab 55 if (tbl_index == -1) {
dkato 0:1c2747611cab 56 sendbuff[OFS_YIADDR + 0] = 0;
dkato 0:1c2747611cab 57 sendbuff[OFS_YIADDR + 1] = 0;
dkato 0:1c2747611cab 58 sendbuff[OFS_YIADDR + 2] = 0;
dkato 0:1c2747611cab 59 sendbuff[OFS_YIADDR + 3] = 0;
dkato 0:1c2747611cab 60 } else {
dkato 0:1c2747611cab 61 sendbuff[OFS_YIADDR + 0] = sendbuff[OFS_SIADDR + 0];
dkato 0:1c2747611cab 62 sendbuff[OFS_YIADDR + 1] = sendbuff[OFS_SIADDR + 1];
dkato 0:1c2747611cab 63 sendbuff[OFS_YIADDR + 2] = sendbuff[OFS_SIADDR + 2];
dkato 0:1c2747611cab 64 sendbuff[OFS_YIADDR + 3] = IP_ADDER_START + tbl_index;
dkato 0:1c2747611cab 65 }
dkato 0:1c2747611cab 66
dkato 0:1c2747611cab 67 sendbuff[OFS_CHADDR + 0] = receivebuff[OFS_CHADDR + 0];
dkato 0:1c2747611cab 68 sendbuff[OFS_CHADDR + 1] = receivebuff[OFS_CHADDR + 1];
dkato 0:1c2747611cab 69 sendbuff[OFS_CHADDR + 2] = receivebuff[OFS_CHADDR + 2];
dkato 0:1c2747611cab 70 sendbuff[OFS_CHADDR + 3] = receivebuff[OFS_CHADDR + 3];
dkato 0:1c2747611cab 71 sendbuff[OFS_CHADDR + 4] = receivebuff[OFS_CHADDR + 4];
dkato 0:1c2747611cab 72 sendbuff[OFS_CHADDR + 5] = receivebuff[OFS_CHADDR + 5];
dkato 0:1c2747611cab 73
dkato 0:1c2747611cab 74 if (receivebuff[OFS_OPTIONS + 2] == DHCP_DISCOVER) {
dkato 0:1c2747611cab 75 sendbuff[OFS_OPTIONS + 2] = DHCP_OFFER;
dkato 0:1c2747611cab 76 if (tbl_index == -1) {
dkato 0:1c2747611cab 77 for (cnt = 0; cnt < CONNECT_NUM; cnt++) {
dkato 0:1c2747611cab 78 if (memcmp( chaddr_tbl[cnt], mac_no_use, 6) == 0) {
dkato 0:1c2747611cab 79 tbl_index = cnt;
dkato 0:1c2747611cab 80 break;
dkato 0:1c2747611cab 81 }
dkato 0:1c2747611cab 82 }
dkato 0:1c2747611cab 83 }
dkato 0:1c2747611cab 84 if (tbl_index != -1) {
dkato 0:1c2747611cab 85 chaddr_tbl[tbl_index][0] = receivebuff[OFS_CHADDR + 0];
dkato 0:1c2747611cab 86 chaddr_tbl[tbl_index][1] = receivebuff[OFS_CHADDR + 1];
dkato 0:1c2747611cab 87 chaddr_tbl[tbl_index][2] = receivebuff[OFS_CHADDR + 2];
dkato 0:1c2747611cab 88 chaddr_tbl[tbl_index][3] = receivebuff[OFS_CHADDR + 3];
dkato 0:1c2747611cab 89 chaddr_tbl[tbl_index][4] = receivebuff[OFS_CHADDR + 4];
dkato 0:1c2747611cab 90 chaddr_tbl[tbl_index][5] = receivebuff[OFS_CHADDR + 5];
dkato 0:1c2747611cab 91 sendbuff[OFS_YIADDR + 0] = sendbuff[OFS_SIADDR + 0];
dkato 0:1c2747611cab 92 sendbuff[OFS_YIADDR + 1] = sendbuff[OFS_SIADDR + 1];
dkato 0:1c2747611cab 93 sendbuff[OFS_YIADDR + 2] = sendbuff[OFS_SIADDR + 2];
dkato 0:1c2747611cab 94 sendbuff[OFS_YIADDR + 3] = IP_ADDER_START + tbl_index;
dkato 0:1c2747611cab 95 }
dkato 0:1c2747611cab 96 dhcp_server.sendTo(client, sendbuff, 300);
dkato 0:1c2747611cab 97 } else if (receivebuff[OFS_OPTIONS + 2] == DHCP_REQUEST) {
dkato 0:1c2747611cab 98 if (tbl_index != -1) {
dkato 0:1c2747611cab 99 sendbuff[OFS_OPTIONS + 2] = DHCP_ACK;
dkato 0:1c2747611cab 100 } else {
dkato 0:1c2747611cab 101 sendbuff[OFS_OPTIONS + 2] = DHCP_NAK;
dkato 0:1c2747611cab 102 }
dkato 0:1c2747611cab 103 dhcp_server.sendTo(client, sendbuff, 300);
dkato 0:1c2747611cab 104 } else if (receivebuff[OFS_OPTIONS + 2] == DHCP_RELEASE) {
dkato 0:1c2747611cab 105 if (tbl_index != -1) {
dkato 0:1c2747611cab 106 memset(chaddr_tbl[tbl_index], 0, 6);
dkato 0:1c2747611cab 107 }
dkato 0:1c2747611cab 108 } else {
dkato 0:1c2747611cab 109 // do nothing
dkato 0:1c2747611cab 110 }
dkato 0:1c2747611cab 111 }
dkato 0:1c2747611cab 112 }
dkato 0:1c2747611cab 113 }
dkato 0:1c2747611cab 114
dkato 0:1c2747611cab 115 DhcpServer::DhcpServer(char * name, char * ipadder) {
dkato 0:1c2747611cab 116 int i;
dkato 0:1c2747611cab 117 int len;
dkato 0:1c2747611cab 118 int ofs;
dkato 0:1c2747611cab 119
dkato 0:1c2747611cab 120 sscanf(ipadder, "%d.%d.%d.%d", (int *)&sendbuff[OFS_SIADDR + 0], (int *)&sendbuff[OFS_SIADDR + 1],
dkato 0:1c2747611cab 121 (int *)&sendbuff[OFS_SIADDR + 2], (int *)&sendbuff[OFS_SIADDR + 3]);
dkato 0:1c2747611cab 122
dkato 0:1c2747611cab 123 len = strlen(name);
dkato 0:1c2747611cab 124 for (i = 0; (i < len) && (i < DHCP_SNAME_LEN); i++) {
dkato 0:1c2747611cab 125 sendbuff[OFS_SNAME + i] = name[i];
dkato 0:1c2747611cab 126 }
dkato 0:1c2747611cab 127
dkato 0:1c2747611cab 128 sendbuff[0] = 0x02;
dkato 0:1c2747611cab 129 sendbuff[1] = 0x01;
dkato 0:1c2747611cab 130 sendbuff[2] = 0x06;
dkato 0:1c2747611cab 131 sendbuff[3] = 0x00;
dkato 0:1c2747611cab 132
dkato 0:1c2747611cab 133 sendbuff[OFS_COOKIE + 0] = 0x63;
dkato 0:1c2747611cab 134 sendbuff[OFS_COOKIE + 1] = 0x82;
dkato 0:1c2747611cab 135 sendbuff[OFS_COOKIE + 2] = 0x53;
dkato 0:1c2747611cab 136 sendbuff[OFS_COOKIE + 3] = 0x63;
dkato 0:1c2747611cab 137
dkato 0:1c2747611cab 138 ofs = OFS_OPTIONS;
dkato 0:1c2747611cab 139 sendbuff[ofs++] = DHCP_OPTION_MESSAGE_TYPE;
dkato 0:1c2747611cab 140 sendbuff[ofs++] = DHCP_OPTION_MESSAGE_TYPE_LEN;
dkato 0:1c2747611cab 141 sendbuff[ofs++] = 0;
dkato 0:1c2747611cab 142
dkato 0:1c2747611cab 143 sendbuff[ofs++] = DHCP_OPTION_SERVER_ID;
dkato 0:1c2747611cab 144 sendbuff[ofs++] = 0x04;
dkato 0:1c2747611cab 145 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 0];
dkato 0:1c2747611cab 146 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 1];
dkato 0:1c2747611cab 147 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 2];
dkato 0:1c2747611cab 148 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 3];
dkato 0:1c2747611cab 149
dkato 0:1c2747611cab 150 sendbuff[ofs++] = DHCP_OPTION_LEASE_TIME;
dkato 0:1c2747611cab 151 sendbuff[ofs++] = 0x04;
dkato 0:1c2747611cab 152 sendbuff[ofs++] = 0x00;
dkato 0:1c2747611cab 153 sendbuff[ofs++] = 0x01;
dkato 0:1c2747611cab 154 sendbuff[ofs++] = 0x4e;
dkato 0:1c2747611cab 155 sendbuff[ofs++] = 0x20;
dkato 0:1c2747611cab 156
dkato 0:1c2747611cab 157 sendbuff[ofs++] = DHCP_OPTION_SUBNET_MASK;
dkato 0:1c2747611cab 158 sendbuff[ofs++] = 0x04;
dkato 0:1c2747611cab 159 sendbuff[ofs++] = 0xff;
dkato 0:1c2747611cab 160 sendbuff[ofs++] = 0xff;
dkato 0:1c2747611cab 161 sendbuff[ofs++] = 0xff;
dkato 0:1c2747611cab 162 sendbuff[ofs++] = 0xf0;
dkato 0:1c2747611cab 163
dkato 0:1c2747611cab 164 sendbuff[ofs++] = DHCP_OPTION_ROUTER;
dkato 0:1c2747611cab 165 sendbuff[ofs++] = 0x04;
dkato 0:1c2747611cab 166 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 0];
dkato 0:1c2747611cab 167 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 1];
dkato 0:1c2747611cab 168 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 2];
dkato 0:1c2747611cab 169 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 3];
dkato 0:1c2747611cab 170
dkato 0:1c2747611cab 171 sendbuff[ofs++] = DHCP_OPTION_DNS_SERVER;
dkato 0:1c2747611cab 172 sendbuff[ofs++] = 0x04;
dkato 0:1c2747611cab 173 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 0];
dkato 0:1c2747611cab 174 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 1];
dkato 0:1c2747611cab 175 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 2];
dkato 0:1c2747611cab 176 sendbuff[ofs++] = sendbuff[OFS_SIADDR + 3];
dkato 0:1c2747611cab 177
dkato 0:1c2747611cab 178 sendbuff[ofs++] = 0xff;
dkato 0:1c2747611cab 179
dkato 0:1c2747611cab 180 if (dhcpThread == NULL) {
dkato 0:1c2747611cab 181 dhcpThread = new Thread(&dhcp_task_static, NULL, osPriorityNormal, (1024 * 8));
dkato 0:1c2747611cab 182 }
dkato 0:1c2747611cab 183 }
dkato 0:1c2747611cab 184
dkato 0:1c2747611cab 185 DhcpServer::~DhcpServer() {
dkato 0:1c2747611cab 186 if (dhcpThread != NULL) {
dkato 0:1c2747611cab 187 delete dhcpThread;
dkato 0:1c2747611cab 188 }
dkato 0:1c2747611cab 189 }