33
34
#define SEGOFS(x) ((SEGMENT(x) << 16) + OFFSET(x))
34
35
#define LINEAR(x) (void *) (((x >> 16) <<4) + (x & 0xFFFF))
37
struct grub_pxe_disk_data
39
grub_uint32_t server_ip;
40
grub_uint32_t gateway_ip;
36
43
struct grub_pxenv *grub_pxe_pxenv;
37
grub_uint32_t grub_pxe_your_ip;
38
grub_uint32_t grub_pxe_server_ip;
39
grub_uint32_t grub_pxe_gateway_ip;
40
int grub_pxe_blksize = GRUB_PXE_MIN_BLKSIZE;
44
static grub_uint32_t grub_pxe_your_ip;
45
static grub_uint32_t grub_pxe_default_server_ip;
46
static grub_uint32_t grub_pxe_default_gateway_ip;
47
static unsigned grub_pxe_blksize = GRUB_PXE_MIN_BLKSIZE;
42
49
static grub_file_t curr_file = 0;
67
parse_ip (const char *val, grub_uint32_t *ip, const char **rest)
69
grub_uint32_t newip = 0;
72
const char *ptr = val;
74
for (i = 0; i < 4; i++)
76
t = grub_strtoul (ptr, (char **) &ptr, 0);
80
return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP.");
83
if (i != 3 && *ptr != '.')
84
return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP.");
60
94
grub_pxe_open (const char *name, grub_disk_t disk)
62
if (grub_strcmp (name, "pxe"))
63
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a pxe disk");
96
struct grub_pxe_disk_data *data;
98
if (grub_strcmp (name, "pxe") != 0
99
&& grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) != 0)
100
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a pxe disk");
102
data = grub_malloc (sizeof (*data));
106
if (grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) == 0)
111
ptr = name + sizeof ("pxe:") - 1;
112
err = parse_ip (ptr, &(data->server_ip), &ptr);
117
err = parse_ip (ptr + 1, &(data->server_ip), 0);
122
data->gateway_ip = grub_pxe_default_gateway_ip;
126
data->server_ip = grub_pxe_default_server_ip;
127
data->gateway_ip = grub_pxe_default_gateway_ip;
65
130
disk->total_sectors = 0;
66
disk->id = (unsigned long) "pxe";
131
disk->id = (unsigned long) data;
68
133
disk->has_partitions = 0;
71
136
return GRUB_ERR_NONE;
75
grub_pxe_close (grub_disk_t disk __attribute((unused)))
140
grub_pxe_close (grub_disk_t disk)
142
grub_free (disk->data);
203
271
if (curr_file != 0)
204
272
grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &o);
206
o.server_ip = grub_pxe_server_ip;
207
o.gateway_ip = grub_pxe_gateway_ip;
274
o.server_ip = disk_data->server_ip;
275
o.gateway_ip = disk_data->gateway_ip;
208
276
grub_strcpy ((char *)&o.filename[0], data->filename);
209
277
o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
210
278
o.packet_size = grub_pxe_blksize;
344
grub_env_write_readonly (struct grub_env_var *var __attribute__ ((unused)),
345
const char *val __attribute__ ((unused)))
351
set_mac_env (grub_uint8_t *mac_addr, grub_size_t mac_len)
353
char buf[(sizeof ("XX:") - 1) * mac_len + 1];
357
for (i = 0; i < mac_len; i++)
359
grub_sprintf (ptr, "%02x:", mac_addr[i] & 0xff);
360
ptr += (sizeof ("XX:") - 1);
367
grub_env_set ("net_pxe_mac", buf);
368
/* XXX: Is it possible to change MAC in PXE? */
369
grub_register_variable_hook ("net_pxe_mac", 0, grub_env_write_readonly);
373
set_env_limn_ro (const char *varname, char *value, grub_size_t len)
378
grub_env_set (varname, value);
380
grub_register_variable_hook (varname, 0, grub_env_write_readonly);
384
parse_dhcp_vendor (void *vend, int limit)
386
grub_uint8_t *ptr, *ptr0;
390
if (grub_be_to_cpu32 (*(grub_uint32_t *) ptr) != 0x63825363)
392
ptr = ptr + sizeof (grub_uint32_t);
393
while (ptr - ptr0 < limit)
395
grub_uint8_t tagtype;
396
grub_uint8_t taglength;
413
set_env_limn_ro ("net_pxe_hostname", (char *) ptr, taglength);
417
set_env_limn_ro ("net_pxe_domain", (char *) ptr, taglength);
421
set_env_limn_ro ("net_pxe_rootpath", (char *) ptr, taglength);
425
set_env_limn_ro ("net_pxe_extensionspath", (char *) ptr, taglength);
428
/* If you need any other options please contact GRUB
429
developpement team. */
276
437
grub_pxe_detect (void)
293
454
bp = LINEAR (ci.buffer);
295
456
grub_pxe_your_ip = bp->your_ip;
296
grub_pxe_server_ip = bp->server_ip;
297
grub_pxe_gateway_ip = bp->gateway_ip;
457
grub_pxe_default_server_ip = bp->server_ip;
458
grub_pxe_default_gateway_ip = bp->gateway_ip;
459
set_mac_env (bp->mac_addr, bp->hw_len < sizeof (bp->mac_addr) ? bp->hw_len
460
: sizeof (bp->mac_addr));
461
set_env_limn_ro ("net_pxe_boot_file", (char *) bp->boot_file,
462
sizeof (bp->boot_file));
463
set_env_limn_ro ("net_pxe_dhcp_server_name", (char *) bp->server_name,
464
sizeof (bp->server_name));
465
parse_dhcp_vendor (&bp->vendor, sizeof (bp->vendor));
299
466
grub_pxe_pxenv = pxenv;
482
set_ip_env (char *varname, grub_uint32_t ip)
484
char buf[sizeof ("XXX.XXX.XXX.XXX")];
486
grub_sprintf (buf, "%d.%d.%d.%d", (ip & 0xff),
487
(ip >> 8) & 0xff, (ip >> 16) & 0xff, (ip >> 24) & 0xff);
488
grub_env_set (varname, buf);
492
write_ip_env (grub_uint32_t *ip, const char *val)
498
err = parse_ip (val, &newip, 0);
502
/* Normalize the IP. */
503
buf = grub_malloc (sizeof ("XXX.XXX.XXX.XXX"));
509
grub_sprintf (buf, "%d.%d.%d.%d", (newip & 0xff), (newip >> 8) & 0xff,
510
(newip >> 16) & 0xff, (newip >> 24) & 0xff);
516
grub_env_write_pxe_default_server (struct grub_env_var *var
517
__attribute__ ((unused)),
520
return write_ip_env (&grub_pxe_default_server_ip, val);
524
grub_env_write_pxe_default_gateway (struct grub_env_var *var
525
__attribute__ ((unused)),
528
return write_ip_env (&grub_pxe_default_gateway_ip, val);
532
grub_env_write_pxe_blocksize (struct grub_env_var *var __attribute__ ((unused)),
538
size = grub_strtoul (val, 0, 0);
542
if (size < GRUB_PXE_MIN_BLKSIZE)
543
size = GRUB_PXE_MIN_BLKSIZE;
544
else if (size > GRUB_PXE_MAX_BLKSIZE)
545
size = GRUB_PXE_MAX_BLKSIZE;
547
buf = grub_malloc (sizeof ("XXXXXX XXXXXX"));
551
grub_sprintf (buf, "%d", size);
552
grub_pxe_blksize = size;
314
558
GRUB_MOD_INIT(pxe)
316
560
grub_pxe_detect ();
317
561
if (grub_pxe_pxenv)
565
buf = grub_malloc (sizeof ("XXXXXX XXXXXX"));
568
grub_sprintf (buf, "%d", grub_pxe_blksize);
569
grub_env_set ("net_pxe_blksize", buf);
572
set_ip_env ("pxe_default_server", grub_pxe_default_server_ip);
573
set_ip_env ("pxe_default_gateway", grub_pxe_default_gateway_ip);
574
set_ip_env ("net_pxe_ip", grub_pxe_your_ip);
575
grub_register_variable_hook ("net_pxe_default_server", 0,
576
grub_env_write_pxe_default_server);
577
grub_register_variable_hook ("net_pxe_default_gateway", 0,
578
grub_env_write_pxe_default_gateway);
580
/* XXX: Is it possible to change IP in PXE? */
581
grub_register_variable_hook ("net_pxe_ip", 0,
582
grub_env_write_readonly);
583
grub_register_variable_hook ("net_pxe_blksize", 0,
584
grub_env_write_pxe_blocksize);
319
585
grub_disk_dev_register (&grub_pxe_dev);
320
586
grub_fs_register (&grub_pxefs_fs);