1/* reserveip.c
2 *
3 * udhcp Server
4 * Copyright (C) 2005 Eric Huang <eric.sy.huang@foxconn.com>
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <fcntl.h>
23#include <string.h>
24#include <stdlib.h>
25#include <stdio.h>
26#include <sys/socket.h>
27#include <netinet/in.h>
28#include <arpa/inet.h>
29
30#include "debug.h"
31#include "dhcpd.h"
32#include "arpping.h"
33#include "socket.h"
34#include "leases.h"
35#include "packet.h"
36#include "serverpacket.h"
37
38int num_of_reservedIP=0;
39char resrvMacAddr[MAX_RESERVED_MAC][MAX_TOKEN_SIZE];
40char resrvIpAddr[MAX_RESERVED_IP][MAX_TOKEN_SIZE];
41
42/*
43 * Strip the ':'s from the MAC address
44 */
45static void trimMacAddr(char *macAddr)
46{
47    #define C_MAX_MACADDR_LEN       18
48    char temp[C_MAX_MACADDR_LEN];
49    char *var = macAddr;
50    int i = 0;
51
52    while (*var)
53    {
54        if (*var != ':')
55        {
56            temp[i++] = *var;
57            if (i == C_MAX_MACADDR_LEN-1)
58            break;
59        }
60            var++;
61    }
62    temp[i] = '\0';
63
64    strcpy(macAddr, temp);
65}
66
67static void HexToAscii (unsigned char *hexKey, unsigned char *asciiKey)
68{
69    unsigned char tmp[32], Data=0, i;
70    for (i=0; i<strlen(hexKey); i++)
71    {
72        tmp[i] = hexKey[i];
73        if (tmp[i] >= '0' && tmp[i] <= '9')
74            Data = Data*0x10 + tmp[i] - 0x30;
75        else if (tmp[i] >= 'A' && tmp[i] <= 'F')
76            Data = Data*0x10 + tmp[i] - 0x37;
77        else if (tmp[i] >= 'a' && tmp[i] <= 'f')
78        {
79
80            Data = Data*0x10 + tmp[i] - 0x57;
81        }
82        if ((i % 2) == 1) {
83            asciiKey[i/2] = Data;
84            Data = 0;
85        }
86    }
87    asciiKey[strlen(hexKey)/2]='\0';
88}
89
90static int getTokens(char *str, char *delimiter, char token[][MAX_TOKEN_SIZE], int maxNumToken)
91{
92    char temp[16*1024];
93    char *field;
94    int numToken=0, i, j;
95    char *ppLast = 0;
96
97    if (strchr(str, '\n')) *(strchr(str, '\n')) = '\0';
98
99    /* Check for empty string */
100    if (str == 0 || str[0] == '\0')
101    {
102        return 0;
103    }
104
105    /* Now get the tokens */
106    strcpy(temp, str);
107
108    for (i=0; i<maxNumToken; i++)
109    {
110        if (i == 0)
111            field = strtok_r(temp, delimiter, &ppLast);
112        else
113            field = strtok_r(NULL, delimiter, &ppLast);
114
115        if (field == NULL || field[0] == '\0')
116        {
117                for (j=i; j<maxNumToken; j++)
118                    token[j][0] = '\0';
119            break;
120        }
121
122        numToken++;
123        strcpy(token[i], field);
124    }
125
126    return numToken;
127}
128
129/*
130 * Read the reserved IP addresses from configuration file and put them into array.
131 * Returns the number of IP address read.
132 */
133int getReservedAddr(char reservedMacAddr[][MAX_TOKEN_SIZE], char reservedIpAddr[][MAX_TOKEN_SIZE])
134{
135#define BUFFER_SIZE     2*1024
136    int numReservedMac=0, numReservedIp=0;
137    char buffer[BUFFER_SIZE];      /* Foxconn modified pling 10/04/2007, to allow max 64 reserved IP */
138    FILE *in;
139
140	if (!(in = fopen("/tmp/udhcpd_resrv.conf", "r")))
141    {
142		LOG(LOG_ERR, "unable to open config file: /tmp/udhcpd_resrv.conf");
143		return 0;
144	}
145
146    /*get ip*/
147    memset(buffer, 0, BUFFER_SIZE);
148    if ( fgets(buffer, BUFFER_SIZE, in) )
149    {
150        numReservedIp = getTokens(buffer, " ", reservedIpAddr, MAX_RESERVED_IP);
151        //LOG(LOG_INFO, "# of reserved ip: %d\n", numReservedIp);
152    }
153    else
154    {
155        //LOG(LOG_ERR, "reserved ip not found.\n");
156        return 0;
157    }
158
159    /*get mac*/
160    memset(buffer, 0, BUFFER_SIZE);
161    if ( fgets(buffer, BUFFER_SIZE, in) )
162    {
163        numReservedMac = getTokens(buffer, " ", reservedMacAddr, MAX_RESERVED_MAC);
164        //LOG(LOG_INFO, "# of reserved mac: %d\n", numReservedIp);
165    }
166    else
167    {
168        //LOG(LOG_ERR, "reserved mac not found.\n");
169        return 0;
170    }
171
172    if (numReservedMac != numReservedIp)
173    {
174        //LOG(LOG_INFO, "WARNING! Reserved IP inconsistency!\n");
175    }
176
177    return (numReservedMac<numReservedIp ? numReservedMac:numReservedIp);
178}
179
180int check_reserved_ip(u_int32_t req_ip, u_int8_t *chaddr)
181{
182    u_int32_t reserved_ip=0;
183    int i=0;
184
185    /* foxconn added start by EricHuang, 02/01/2007 */
186    //if ( ntohl(req_ip) == server_config.server ) //foxconn modified, wenchia, 2007/09/10
187    if ( ntohl(req_ip) == ntohl(server_config.server) )
188    {
189        return 0; /* requested ip is router's ip */
190    }
191    /* foxconn added end by EricHuang, 02/01/2007 */
192
193    for (i=0; i<num_of_reservedIP; i++)
194    {
195        reserved_ip = inet_addr(resrvIpAddr[i]);
196        /*Foxconn modify start,Zz Shan@Reserved ip 05/07/2008*/
197        //if ( reserved_ip == ntohl(req_ip) )
198        if ( reserved_ip == (req_ip) )
199        /*Foxconn modify end,Zz Shan@Reserved ip 05/07/2008*/
200        {
201            unsigned char tempMac[32], mac[7];
202            sprintf(tempMac, "%s", resrvMacAddr[i]);
203            trimMacAddr(tempMac);
204            HexToAscii(tempMac, mac);
205            if ( memcmp(chaddr, mac, 6) == 0 )
206            {
207                return 1; /*reserved ip and the ip reserved for this mac*/
208            }
209
210            return 0; /*reserved ip but not for this mac*/
211        }
212    }
213
214    return 1; /*not a reserved ip*/
215}
216
217u_int32_t find_reserved_ip(u_int8_t *chaddr)
218{
219    int i;
220
221    for (i=0; i<num_of_reservedIP; i++)
222    {
223        unsigned char tempMac[32], mac[7];
224        sprintf(tempMac, "%s", resrvMacAddr[i]);
225        trimMacAddr(tempMac);
226        HexToAscii(tempMac, mac);
227        if ( memcmp(chaddr, mac, 6) == 0 )
228        {
229            /*reserved ip found for this mac*/
230            return ntohl(inet_addr(resrvIpAddr[i]));
231        }
232    }
233
234    return 0;   /* Sorry, no reserved ip found */
235}
236