Revision 460fec67 slirp/bootp.c

b/slirp/bootp.c
25 25

  
26 26
/* XXX: only DHCP is supported */
27 27

  
28
#define NB_ADDR 16
29

  
30 28
#define LEASE_TIME (24 * 3600)
31 29

  
32
typedef struct {
33
    uint8_t allocated;
34
    uint8_t macaddr[6];
35
} BOOTPClient;
36

  
37
static BOOTPClient bootp_clients[NB_ADDR];
38

  
39
char *bootp_filename;
40

  
41 30
static const uint8_t rfc1533_cookie[] = { RFC1533_COOKIE };
42 31

  
43 32
#ifdef DEBUG
......
47 36
#define dprintf(fmt, ...)
48 37
#endif
49 38

  
50
static BOOTPClient *get_new_addr(struct in_addr *paddr,
39
static BOOTPClient *get_new_addr(Slirp *slirp, struct in_addr *paddr,
51 40
                                 const uint8_t *macaddr)
52 41
{
53 42
    BOOTPClient *bc;
54 43
    int i;
55 44

  
56
    for(i = 0; i < NB_ADDR; i++) {
57
        bc = &bootp_clients[i];
45
    for(i = 0; i < NB_BOOTP_CLIENTS; i++) {
46
        bc = &slirp->bootp_clients[i];
58 47
        if (!bc->allocated || !memcmp(macaddr, bc->macaddr, 6))
59 48
            goto found;
60 49
    }
61 50
    return NULL;
62 51
 found:
63
    bc = &bootp_clients[i];
52
    bc = &slirp->bootp_clients[i];
64 53
    bc->allocated = 1;
65
    paddr->s_addr = vdhcp_startaddr.s_addr + htonl(i);
54
    paddr->s_addr = slirp->vdhcp_startaddr.s_addr + htonl(i);
66 55
    return bc;
67 56
}
68 57

  
69
static BOOTPClient *request_addr(const struct in_addr *paddr,
58
static BOOTPClient *request_addr(Slirp *slirp, const struct in_addr *paddr,
70 59
                                 const uint8_t *macaddr)
71 60
{
72 61
    uint32_t req_addr = ntohl(paddr->s_addr);
73
    uint32_t dhcp_addr = ntohl(vdhcp_startaddr.s_addr);
62
    uint32_t dhcp_addr = ntohl(slirp->vdhcp_startaddr.s_addr);
74 63
    BOOTPClient *bc;
75 64

  
76 65
    if (req_addr >= dhcp_addr &&
77
        req_addr < (dhcp_addr + NB_ADDR)) {
78
        bc = &bootp_clients[req_addr - dhcp_addr];
66
        req_addr < (dhcp_addr + NB_BOOTP_CLIENTS)) {
67
        bc = &slirp->bootp_clients[req_addr - dhcp_addr];
79 68
        if (!bc->allocated || !memcmp(macaddr, bc->macaddr, 6)) {
80 69
            bc->allocated = 1;
81 70
            return bc;
......
84 73
    return NULL;
85 74
}
86 75

  
87
static BOOTPClient *find_addr(struct in_addr *paddr, const uint8_t *macaddr)
76
static BOOTPClient *find_addr(Slirp *slirp, struct in_addr *paddr,
77
                              const uint8_t *macaddr)
88 78
{
89 79
    BOOTPClient *bc;
90 80
    int i;
91 81

  
92
    for(i = 0; i < NB_ADDR; i++) {
93
        if (!memcmp(macaddr, bootp_clients[i].macaddr, 6))
82
    for(i = 0; i < NB_BOOTP_CLIENTS; i++) {
83
        if (!memcmp(macaddr, slirp->bootp_clients[i].macaddr, 6))
94 84
            goto found;
95 85
    }
96 86
    return NULL;
97 87
 found:
98
    bc = &bootp_clients[i];
88
    bc = &slirp->bootp_clients[i];
99 89
    bc->allocated = 1;
100
    paddr->s_addr = vdhcp_startaddr.s_addr + htonl(i);
90
    paddr->s_addr = slirp->vdhcp_startaddr.s_addr + htonl(i);
101 91
    return bc;
102 92
}
103 93

  
......
148 138
    }
149 139
}
150 140

  
151
static void bootp_reply(const struct bootp_t *bp)
141
static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
152 142
{
153 143
    BOOTPClient *bc = NULL;
154 144
    struct mbuf *m;
......
173 163
        dhcp_msg_type != DHCPREQUEST)
174 164
        return;
175 165
    /* XXX: this is a hack to get the client mac address */
176
    memcpy(client_ethaddr, bp->bp_hwaddr, 6);
166
    memcpy(slirp->client_ethaddr, bp->bp_hwaddr, 6);
177 167

  
178
    if ((m = m_get()) == NULL)
168
    m = m_get(slirp);
169
    if (!m) {
179 170
        return;
171
    }
180 172
    m->m_data += IF_MAXLINKHDR;
181 173
    rbp = (struct bootp_t *)m->m_data;
182 174
    m->m_data += sizeof(struct udpiphdr);
......
184 176

  
185 177
    if (dhcp_msg_type == DHCPDISCOVER) {
186 178
        if (preq_addr) {
187
            bc = request_addr(preq_addr, client_ethaddr);
179
            bc = request_addr(slirp, preq_addr, slirp->client_ethaddr);
188 180
            if (bc) {
189 181
                daddr.sin_addr = *preq_addr;
190 182
            }
191 183
        }
192 184
        if (!bc) {
193 185
         new_addr:
194
            bc = get_new_addr(&daddr.sin_addr, client_ethaddr);
186
            bc = get_new_addr(slirp, &daddr.sin_addr, slirp->client_ethaddr);
195 187
            if (!bc) {
196 188
                dprintf("no address left\n");
197 189
                return;
198 190
            }
199 191
        }
200
        memcpy(bc->macaddr, client_ethaddr, 6);
192
        memcpy(bc->macaddr, slirp->client_ethaddr, 6);
201 193
    } else if (preq_addr) {
202
        bc = request_addr(preq_addr, client_ethaddr);
194
        bc = request_addr(slirp, preq_addr, slirp->client_ethaddr);
203 195
        if (bc) {
204 196
            daddr.sin_addr = *preq_addr;
205
            memcpy(bc->macaddr, client_ethaddr, 6);
197
            memcpy(bc->macaddr, slirp->client_ethaddr, 6);
206 198
        } else {
207 199
            daddr.sin_addr.s_addr = 0;
208 200
        }
209 201
    } else {
210
        bc = find_addr(&daddr.sin_addr, bp->bp_hwaddr);
202
        bc = find_addr(slirp, &daddr.sin_addr, bp->bp_hwaddr);
211 203
        if (!bc) {
212 204
            /* if never assigned, behaves as if it was already
213 205
               assigned (windows fix because it remembers its address) */
......
215 207
        }
216 208
    }
217 209

  
218
    saddr.sin_addr = vhost_addr;
210
    saddr.sin_addr = slirp->vhost_addr;
219 211
    saddr.sin_port = htons(BOOTP_SERVER);
220 212

  
221 213
    daddr.sin_port = htons(BOOTP_CLIENT);
......
248 240
            *q++ = DHCPACK;
249 241
        }
250 242

  
251
        if (bootp_filename)
243
        if (slirp->bootp_filename)
252 244
            snprintf((char *)rbp->bp_file, sizeof(rbp->bp_file), "%s",
253
                     bootp_filename);
245
                     slirp->bootp_filename);
254 246

  
255 247
        *q++ = RFC2132_SRV_ID;
256 248
        *q++ = 4;
......
259 251

  
260 252
        *q++ = RFC1533_NETMASK;
261 253
        *q++ = 4;
262
        memcpy(q, &vnetwork_mask, 4);
254
        memcpy(q, &slirp->vnetwork_mask, 4);
263 255
        q += 4;
264 256

  
265
        if (!slirp_restrict) {
257
        if (!slirp->restricted) {
266 258
            *q++ = RFC1533_GATEWAY;
267 259
            *q++ = 4;
268 260
            memcpy(q, &saddr.sin_addr, 4);
......
270 262

  
271 263
            *q++ = RFC1533_DNS;
272 264
            *q++ = 4;
273
            memcpy(q, &vnameserver_addr, 4);
265
            memcpy(q, &slirp->vnameserver_addr, 4);
274 266
            q += 4;
275 267
        }
276 268

  
......
280 272
        memcpy(q, &val, 4);
281 273
        q += 4;
282 274

  
283
        if (*slirp_hostname) {
284
            val = strlen(slirp_hostname);
275
        if (*slirp->client_hostname) {
276
            val = strlen(slirp->client_hostname);
285 277
            *q++ = RFC1533_HOSTNAME;
286 278
            *q++ = val;
287
            memcpy(q, slirp_hostname, val);
279
            memcpy(q, slirp->client_hostname, val);
288 280
            q += val;
289 281
        }
290 282
    } else {
......
315 307
    struct bootp_t *bp = mtod(m, struct bootp_t *);
316 308

  
317 309
    if (bp->bp_op == BOOTP_REQUEST) {
318
        bootp_reply(bp);
310
        bootp_reply(m->slirp, bp);
319 311
    }
320 312
}

Also available in: Unified diff