2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2010,2011,2012,2013 Free Software Foundation, Inc.
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
20 #include <grub/net/netbuff.h>
21 #include <grub/time.h>
22 #include <grub/file.h>
23 #include <grub/i18n.h>
25 #include <grub/misc.h>
27 #include <grub/command.h>
29 #include <grub/net/ethernet.h>
30 #include <grub/net/arp.h>
31 #include <grub/net/ip.h>
32 #include <grub/loader.h>
33 #include <grub/bufio.h>
34 #include <grub/kernel.h>
36 GRUB_MOD_LICENSE ("GPLv3+");
38 char *grub_net_default_server
;
40 struct grub_net_route
*grub_net_routes
= NULL
;
41 struct grub_net_network_level_interface
*grub_net_network_level_interfaces
= NULL
;
42 struct grub_net_card
*grub_net_cards
= NULL
;
43 struct grub_net_network_level_protocol
*grub_net_network_level_protocols
= NULL
;
44 static struct grub_fs grub_net_fs
;
46 struct grub_net_link_layer_entry
{
48 grub_net_network_level_address_t nl_address
;
49 grub_net_link_level_address_t ll_address
;
52 #define LINK_LAYER_CACHE_SIZE 256
54 static struct grub_net_link_layer_entry
*
55 link_layer_find_entry (const grub_net_network_level_address_t
*proto
,
56 const struct grub_net_card
*card
)
59 if (!card
->link_layer_table
)
61 for (i
= 0; i
< LINK_LAYER_CACHE_SIZE
; i
++)
63 if (card
->link_layer_table
[i
].avail
== 1
64 && grub_net_addr_cmp (&card
->link_layer_table
[i
].nl_address
,
66 return &card
->link_layer_table
[i
];
72 grub_net_link_layer_add_address (struct grub_net_card
*card
,
73 const grub_net_network_level_address_t
*nl
,
74 const grub_net_link_level_address_t
*ll
,
77 struct grub_net_link_layer_entry
*entry
;
79 /* Check if the sender is in the cache table. */
80 entry
= link_layer_find_entry (nl
, card
);
81 /* Update sender hardware address. */
82 if (entry
&& override
)
83 grub_memcpy (&entry
->ll_address
, ll
, sizeof (entry
->ll_address
));
87 /* Add sender to cache table. */
88 if (card
->link_layer_table
== NULL
)
89 card
->link_layer_table
= grub_zalloc (LINK_LAYER_CACHE_SIZE
90 * sizeof (card
->link_layer_table
[0]));
91 entry
= &(card
->link_layer_table
[card
->new_ll_entry
]);
93 grub_memcpy (&entry
->ll_address
, ll
, sizeof (entry
->ll_address
));
94 grub_memcpy (&entry
->nl_address
, nl
, sizeof (entry
->nl_address
));
96 if (card
->new_ll_entry
== LINK_LAYER_CACHE_SIZE
)
97 card
->new_ll_entry
= 0;
101 grub_net_link_layer_resolve_check (struct grub_net_network_level_interface
*inf
,
102 const grub_net_network_level_address_t
*proto_addr
)
104 struct grub_net_link_layer_entry
*entry
;
106 if (proto_addr
->type
== GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
107 && proto_addr
->ipv4
== 0xffffffff)
109 entry
= link_layer_find_entry (proto_addr
, inf
->card
);
116 grub_net_link_layer_resolve (struct grub_net_network_level_interface
*inf
,
117 const grub_net_network_level_address_t
*proto_addr
,
118 grub_net_link_level_address_t
*hw_addr
)
120 struct grub_net_link_layer_entry
*entry
;
123 if ((proto_addr
->type
== GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
124 && proto_addr
->ipv4
== 0xffffffff)
125 || proto_addr
->type
== GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV
126 || (proto_addr
->type
== GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
127 && proto_addr
->ipv6
[0] == grub_be_to_cpu64_compile_time (0xff02ULL
129 && proto_addr
->ipv6
[1] == (grub_be_to_cpu64_compile_time (1))))
131 hw_addr
->type
= GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET
;
132 grub_memset (hw_addr
->mac
, -1, 6);
133 return GRUB_ERR_NONE
;
136 if (proto_addr
->type
== GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
137 && ((grub_be_to_cpu64 (proto_addr
->ipv6
[0]) >> 56) == 0xff))
139 hw_addr
->type
= GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET
;
140 hw_addr
->mac
[0] = 0x33;
141 hw_addr
->mac
[1] = 0x33;
142 hw_addr
->mac
[2] = ((grub_be_to_cpu64 (proto_addr
->ipv6
[1]) >> 24) & 0xff);
143 hw_addr
->mac
[3] = ((grub_be_to_cpu64 (proto_addr
->ipv6
[1]) >> 16) & 0xff);
144 hw_addr
->mac
[4] = ((grub_be_to_cpu64 (proto_addr
->ipv6
[1]) >> 8) & 0xff);
145 hw_addr
->mac
[5] = ((grub_be_to_cpu64 (proto_addr
->ipv6
[1]) >> 0) & 0xff);
146 return GRUB_ERR_NONE
;
149 /* Check cache table. */
150 entry
= link_layer_find_entry (proto_addr
, inf
->card
);
153 *hw_addr
= entry
->ll_address
;
154 return GRUB_ERR_NONE
;
156 switch (proto_addr
->type
)
158 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
:
159 err
= grub_net_arp_send_request (inf
, proto_addr
);
161 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
:
162 err
= grub_net_icmp6_send_request (inf
, proto_addr
);
164 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV
:
165 return grub_error (GRUB_ERR_BUG
, "shouldn't reach here");
167 return grub_error (GRUB_ERR_BUG
,
168 "unsupported address type %d", proto_addr
->type
);
172 entry
= link_layer_find_entry (proto_addr
, inf
->card
);
175 *hw_addr
= entry
->ll_address
;
176 return GRUB_ERR_NONE
;
178 return grub_error (GRUB_ERR_TIMEOUT
,
179 N_("timeout: could not resolve hardware address"));
183 grub_net_card_unregister (struct grub_net_card
*card
)
185 struct grub_net_network_level_interface
*inf
, *next
;
186 FOR_NET_NETWORK_LEVEL_INTERFACES_SAFE(inf
, next
)
187 if (inf
->card
== card
)
188 grub_net_network_level_interface_unregister (inf
);
191 if (card
->driver
->close
)
192 card
->driver
->close (card
);
195 grub_list_remove (GRUB_AS_LIST (card
));
198 static struct grub_net_slaac_mac_list
*
199 grub_net_ipv6_get_slaac (struct grub_net_card
*card
,
200 const grub_net_link_level_address_t
*hwaddr
)
202 struct grub_net_slaac_mac_list
*slaac
;
205 for (slaac
= card
->slaac_list
; slaac
; slaac
= slaac
->next
)
206 if (grub_net_hwaddr_cmp (&slaac
->address
, hwaddr
) == 0)
209 slaac
= grub_zalloc (sizeof (*slaac
));
213 slaac
->name
= grub_malloc (grub_strlen (card
->name
)
214 + GRUB_NET_MAX_STR_HWADDR_LEN
215 + sizeof (":slaac"));
216 ptr
= grub_stpcpy (slaac
->name
, card
->name
);
217 if (grub_net_hwaddr_cmp (&card
->default_address
, hwaddr
) != 0)
219 ptr
= grub_stpcpy (ptr
, ":");
220 grub_net_hwaddr_to_str (hwaddr
, ptr
);
221 ptr
+= grub_strlen (ptr
);
223 ptr
= grub_stpcpy (ptr
, ":slaac");
225 grub_memcpy (&slaac
->address
, hwaddr
, sizeof (slaac
->address
));
226 slaac
->next
= card
->slaac_list
;
227 card
->slaac_list
= slaac
;
232 grub_net_network_level_interface_register (struct grub_net_network_level_interface
*inter
);
234 static struct grub_net_network_level_interface
*
235 grub_net_add_addr_real (char *name
,
236 struct grub_net_card
*card
,
237 const grub_net_network_level_address_t
*addr
,
238 const grub_net_link_level_address_t
*hwaddress
,
239 grub_net_interface_flags_t flags
)
241 struct grub_net_network_level_interface
*inter
;
243 inter
= grub_zalloc (sizeof (*inter
));
248 grub_memcpy (&(inter
->address
), addr
, sizeof (inter
->address
));
249 grub_memcpy (&(inter
->hwaddress
), hwaddress
, sizeof (inter
->hwaddress
));
250 inter
->flags
= flags
;
252 inter
->dhcp_ack
= NULL
;
253 inter
->dhcp_acklen
= 0;
255 grub_net_network_level_interface_register (inter
);
260 struct grub_net_network_level_interface
*
261 grub_net_add_addr (const char *name
,
262 struct grub_net_card
*card
,
263 const grub_net_network_level_address_t
*addr
,
264 const grub_net_link_level_address_t
*hwaddress
,
265 grub_net_interface_flags_t flags
)
267 char *name_dup
= grub_strdup (name
);
268 struct grub_net_network_level_interface
*ret
;
272 ret
= grub_net_add_addr_real (name_dup
, card
, addr
, hwaddress
, flags
);
274 grub_free (name_dup
);
278 struct grub_net_network_level_interface
*
279 grub_net_ipv6_get_link_local (struct grub_net_card
*card
,
280 const grub_net_link_level_address_t
*hwaddr
)
282 struct grub_net_network_level_interface
*inf
;
285 grub_net_network_level_address_t addr
;
287 addr
.type
= GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
;
288 addr
.ipv6
[0] = grub_cpu_to_be64_compile_time (0xfe80ULL
<< 48);
289 addr
.ipv6
[1] = grub_net_ipv6_get_id (hwaddr
);
291 FOR_NET_NETWORK_LEVEL_INTERFACES (inf
)
293 if (inf
->card
== card
294 && grub_net_hwaddr_cmp (&inf
->hwaddress
, hwaddr
) == 0
295 && grub_net_addr_cmp (&inf
->address
, &addr
) == 0)
299 name
= grub_malloc (grub_strlen (card
->name
)
300 + GRUB_NET_MAX_STR_HWADDR_LEN
305 ptr
= grub_stpcpy (name
, card
->name
);
306 if (grub_net_hwaddr_cmp (&card
->default_address
, hwaddr
) != 0)
308 ptr
= grub_stpcpy (ptr
, ":");
309 grub_net_hwaddr_to_str (hwaddr
, ptr
);
310 ptr
+= grub_strlen (ptr
);
312 ptr
= grub_stpcpy (ptr
, ":link");
313 return grub_net_add_addr_real (name
, card
, &addr
, hwaddr
, 0);
316 /* FIXME: allow to specify mac address. */
318 grub_cmd_ipv6_autoconf (struct grub_command
*cmd
__attribute__ ((unused
)),
319 int argc
, char **args
)
321 struct grub_net_card
*card
;
322 struct grub_net_network_level_interface
**ifaces
;
323 grub_size_t ncards
= 0;
327 struct grub_net_slaac_mac_list
**slaacs
;
331 if (argc
> 0 && grub_strcmp (card
->name
, args
[0]) != 0)
336 ifaces
= grub_zalloc (ncards
* sizeof (ifaces
[0]));
337 slaacs
= grub_zalloc (ncards
* sizeof (slaacs
[0]));
338 if (!ifaces
|| !slaacs
)
347 if (argc
> 0 && grub_strcmp (card
->name
, args
[0]) != 0)
349 ifaces
[j
] = grub_net_ipv6_get_link_local (card
, &card
->default_address
);
356 slaacs
[j
] = grub_net_ipv6_get_slaac (card
, &card
->default_address
);
366 for (interval
= 200; interval
< 10000; interval
*= 2)
369 for (j
= 0; j
< ncards
; j
++)
371 if (slaacs
[j
]->slaac_counter
)
373 err
= grub_net_icmp6_send_router_solicit (ifaces
[j
]);
380 grub_net_poll_cards (interval
, 0);
384 for (j
= 0; j
< ncards
; j
++)
386 if (slaacs
[j
]->slaac_counter
)
388 err
= grub_error (GRUB_ERR_FILE_NOT_FOUND
,
389 N_("couldn't autoconfigure %s"),
390 ifaces
[j
]->card
->name
);
400 parse_ip (const char *val
, grub_uint32_t
*ip
, const char **rest
)
402 grub_uint32_t newip
= 0;
404 const char *ptr
= val
;
406 for (i
= 0; i
< 4; i
++)
409 t
= grub_strtoul (ptr
, (char **) &ptr
, 0);
412 grub_errno
= GRUB_ERR_NONE
;
415 if (*ptr
!= '.' && i
== 0)
424 if (i
!= 3 && *ptr
!= '.')
428 *ip
= grub_cpu_to_le32 (newip
);
435 parse_ip6 (const char *val
, grub_uint64_t
*ip
, const char **rest
)
437 grub_uint16_t newip
[8];
438 const char *ptr
= val
;
439 int word
, quaddot
= -1;
441 if (ptr
[0] == ':' && ptr
[1] != ':')
446 for (word
= 0; word
< 8; word
++)
456 t
= grub_strtoul (ptr
, (char **) &ptr
, 16);
459 grub_errno
= GRUB_ERR_NONE
;
464 newip
[word
] = grub_cpu_to_be16 (t
);
469 if (quaddot
== -1 && word
< 7)
473 grub_memmove (&newip
[quaddot
+ 7 - word
], &newip
[quaddot
],
474 (word
- quaddot
+ 1) * sizeof (newip
[0]));
475 grub_memset (&newip
[quaddot
], 0, (7 - word
) * sizeof (newip
[0]));
477 grub_memcpy (ip
, newip
, 16);
484 match_net (const grub_net_network_level_netaddress_t
*net
,
485 const grub_net_network_level_address_t
*addr
)
487 if (net
->type
!= addr
->type
)
491 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV
:
493 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
:
495 grub_uint32_t mask
= (0xffffffffU
<< (32 - net
->ipv4
.masksize
));
496 if (net
->ipv4
.masksize
== 0)
498 return ((grub_be_to_cpu32 (net
->ipv4
.base
) & mask
)
499 == (grub_be_to_cpu32 (addr
->ipv4
) & mask
));
501 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
:
503 grub_uint64_t mask
[2];
504 if (net
->ipv6
.masksize
== 0)
506 if (net
->ipv6
.masksize
<= 64)
508 mask
[0] = 0xffffffffffffffffULL
<< (64 - net
->ipv6
.masksize
);
513 mask
[0] = 0xffffffffffffffffULL
;
514 mask
[1] = 0xffffffffffffffffULL
<< (128 - net
->ipv6
.masksize
);
516 return (((grub_be_to_cpu64 (net
->ipv6
.base
[0]) & mask
[0])
517 == (grub_be_to_cpu64 (addr
->ipv6
[0]) & mask
[0]))
518 && ((grub_be_to_cpu64 (net
->ipv6
.base
[1]) & mask
[1])
519 == (grub_be_to_cpu64 (addr
->ipv6
[1]) & mask
[1])));
526 grub_net_resolve_address (const char *name
,
527 grub_net_network_level_address_t
*addr
)
531 grub_size_t naddresses
;
532 struct grub_net_network_level_address
*addresses
= 0;
534 if (parse_ip (name
, &addr
->ipv4
, &rest
) && *rest
== 0)
536 addr
->type
= GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
;
537 return GRUB_ERR_NONE
;
539 if (parse_ip6 (name
, addr
->ipv6
, &rest
) && *rest
== 0)
541 addr
->type
= GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
;
542 return GRUB_ERR_NONE
;
544 err
= grub_net_dns_lookup (name
, 0, 0, &naddresses
, &addresses
, 1);
548 grub_error (GRUB_ERR_NET_BAD_ADDRESS
, N_("unresolvable address %s"),
550 /* FIXME: use other results as well. */
551 *addr
= addresses
[0];
552 grub_free (addresses
);
553 return GRUB_ERR_NONE
;
557 grub_net_resolve_net_address (const char *name
,
558 grub_net_network_level_netaddress_t
*addr
)
561 if (parse_ip (name
, &addr
->ipv4
.base
, &rest
))
563 addr
->type
= GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
;
566 addr
->ipv4
.masksize
= grub_strtoul (rest
+ 1, (char **) &rest
, 0);
567 if (!grub_errno
&& *rest
== 0)
568 return GRUB_ERR_NONE
;
569 grub_errno
= GRUB_ERR_NONE
;
573 addr
->ipv4
.masksize
= 32;
574 return GRUB_ERR_NONE
;
577 if (parse_ip6 (name
, addr
->ipv6
.base
, &rest
))
579 addr
->type
= GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
;
582 addr
->ipv6
.masksize
= grub_strtoul (rest
+ 1, (char **) &rest
, 0);
583 if (!grub_errno
&& *rest
== 0)
584 return GRUB_ERR_NONE
;
585 grub_errno
= GRUB_ERR_NONE
;
589 addr
->ipv6
.masksize
= 128;
590 return GRUB_ERR_NONE
;
593 return grub_error (GRUB_ERR_NET_BAD_ADDRESS
,
594 N_("unrecognised network address `%s'"),
599 route_cmp (const struct grub_net_route
*a
, const struct grub_net_route
*b
)
601 if (a
== NULL
&& b
== NULL
)
607 if (a
->target
.type
< b
->target
.type
)
609 if (a
->target
.type
> b
->target
.type
)
611 switch (a
->target
.type
)
613 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV
:
615 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
:
616 if (a
->target
.ipv6
.masksize
> b
->target
.ipv6
.masksize
)
618 if (a
->target
.ipv6
.masksize
< b
->target
.ipv6
.masksize
)
621 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
:
622 if (a
->target
.ipv4
.masksize
> b
->target
.ipv4
.masksize
)
624 if (a
->target
.ipv4
.masksize
< b
->target
.ipv4
.masksize
)
632 grub_net_route_address (grub_net_network_level_address_t addr
,
633 grub_net_network_level_address_t
*gateway
,
634 struct grub_net_network_level_interface
**interf
)
636 struct grub_net_route
*route
;
637 unsigned int depth
= 0;
638 unsigned int routecnt
= 0;
639 struct grub_net_network_level_protocol
*prot
= NULL
;
640 grub_net_network_level_address_t curtarget
= addr
;
644 FOR_NET_ROUTES(route
)
647 for (depth
= 0; depth
< routecnt
+ 2 && depth
< GRUB_UINT_MAX
; depth
++)
649 struct grub_net_route
*bestroute
= NULL
;
650 FOR_NET_ROUTES(route
)
652 if (depth
&& prot
!= route
->prot
)
654 if (!match_net (&route
->target
, &curtarget
))
656 if (route_cmp (route
, bestroute
) > 0)
659 if (bestroute
== NULL
)
660 return grub_error (GRUB_ERR_NET_NO_ROUTE
,
661 N_("destination unreachable"));
663 if (!bestroute
->is_gateway
)
665 *interf
= bestroute
->interface
;
666 return GRUB_ERR_NONE
;
670 *gateway
= bestroute
->gw
;
671 if (bestroute
->interface
!= NULL
)
673 *interf
= bestroute
->interface
;
674 return GRUB_ERR_NONE
;
677 curtarget
= bestroute
->gw
;
680 return grub_error (GRUB_ERR_NET_ROUTE_LOOP
,
681 /* TRANSLATORS: route loop is a condition when e.g.
682 to contact server A you need to go through B
683 and to contact B you need to go through A. */
684 N_("route loop detected"));
688 grub_cmd_deladdr (struct grub_command
*cmd
__attribute__ ((unused
)),
689 int argc
, char **args
)
691 struct grub_net_network_level_interface
*inter
;
694 return grub_error (GRUB_ERR_BAD_ARGUMENT
, N_("one argument expected"));
696 FOR_NET_NETWORK_LEVEL_INTERFACES (inter
)
697 if (grub_strcmp (inter
->name
, args
[0]) == 0)
700 return grub_error (GRUB_ERR_BAD_ARGUMENT
, N_("address not found"));
702 if (inter
->flags
& GRUB_NET_INTERFACE_PERMANENT
)
703 return grub_error (GRUB_ERR_IO
,
704 N_("you can't delete this address"));
706 grub_net_network_level_interface_unregister (inter
);
707 grub_free (inter
->name
);
710 return GRUB_ERR_NONE
;
714 grub_net_addr_to_str (const grub_net_network_level_address_t
*target
, char *buf
)
716 switch (target
->type
)
718 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV
:
719 COMPILE_TIME_ASSERT (sizeof ("temporary") < GRUB_NET_MAX_STR_ADDR_LEN
);
720 grub_strcpy (buf
, "temporary");
722 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
:
725 grub_uint64_t n
= grub_be_to_cpu64 (target
->ipv6
[0]);
727 for (i
= 0; i
< 4; i
++)
729 grub_snprintf (ptr
, 6, "%" PRIxGRUB_UINT64_T
":",
730 (n
>> (48 - 16 * i
)) & 0xffff);
731 ptr
+= grub_strlen (ptr
);
733 n
= grub_be_to_cpu64 (target
->ipv6
[1]);
734 for (i
= 0; i
< 3; i
++)
736 grub_snprintf (ptr
, 6, "%" PRIxGRUB_UINT64_T
":",
737 (n
>> (48 - 16 * i
)) & 0xffff);
738 ptr
+= grub_strlen (ptr
);
740 grub_snprintf (ptr
, 5, "%" PRIxGRUB_UINT64_T
, n
& 0xffff);
743 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
:
745 grub_uint32_t n
= grub_be_to_cpu32 (target
->ipv4
);
746 grub_snprintf (buf
, GRUB_NET_MAX_STR_ADDR_LEN
, "%d.%d.%d.%d",
747 ((n
>> 24) & 0xff), ((n
>> 16) & 0xff),
748 ((n
>> 8) & 0xff), ((n
>> 0) & 0xff));
752 grub_snprintf (buf
, GRUB_NET_MAX_STR_ADDR_LEN
,
753 "Unknown address type %d", target
->type
);
758 grub_net_hwaddr_to_str (const grub_net_link_level_address_t
*addr
, char *str
)
763 case GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET
:
767 for (ptr
= str
, i
= 0; i
< ARRAY_SIZE (addr
->mac
); i
++)
769 grub_snprintf (ptr
, GRUB_NET_MAX_STR_HWADDR_LEN
- (ptr
- str
),
770 "%02x:", addr
->mac
[i
] & 0xff);
771 ptr
+= (sizeof ("XX:") - 1);
776 grub_printf (_("Unsupported hw address type %d\n"), addr
->type
);
780 grub_net_hwaddr_cmp (const grub_net_link_level_address_t
*a
,
781 const grub_net_link_level_address_t
*b
)
783 if (a
->type
< b
->type
)
785 if (a
->type
> b
->type
)
789 case GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET
:
790 return grub_memcmp (a
->mac
, b
->mac
, sizeof (a
->mac
));
792 grub_printf (_("Unsupported hw address type %d\n"), a
->type
);
797 grub_net_addr_cmp (const grub_net_network_level_address_t
*a
,
798 const grub_net_network_level_address_t
*b
)
800 if (a
->type
< b
->type
)
802 if (a
->type
> b
->type
)
806 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
:
807 return grub_memcmp (&a
->ipv4
, &b
->ipv4
, sizeof (a
->ipv4
));
808 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
:
809 return grub_memcmp (&a
->ipv6
, &b
->ipv6
, sizeof (a
->ipv6
));
810 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV
:
813 grub_printf (_("Unsupported address type %d\n"), a
->type
);
817 /* FIXME: implement this. */
819 hwaddr_set_env (struct grub_env_var
*var
__attribute__ ((unused
)),
820 const char *val
__attribute__ ((unused
)))
825 /* FIXME: implement this. */
827 addr_set_env (struct grub_env_var
*var
__attribute__ ((unused
)),
828 const char *val
__attribute__ ((unused
)))
834 defserver_set_env (struct grub_env_var
*var
__attribute__ ((unused
)),
837 grub_free (grub_net_default_server
);
838 grub_net_default_server
= grub_strdup (val
);
839 return grub_strdup (val
);
843 defserver_get_env (struct grub_env_var
*var
__attribute__ ((unused
)),
844 const char *val
__attribute__ ((unused
)))
846 return grub_net_default_server
? : "";
850 defip_get_env (struct grub_env_var
*var
__attribute__ ((unused
)),
851 const char *val
__attribute__ ((unused
)))
853 const char *intf
= grub_env_get ("net_default_interface");
854 const char *ret
= NULL
;
857 char *buf
= grub_xasprintf ("net_%s_ip", intf
);
859 ret
= grub_env_get (buf
);
866 defip_set_env (struct grub_env_var
*var
__attribute__ ((unused
)),
869 const char *intf
= grub_env_get ("net_default_interface");
872 char *buf
= grub_xasprintf ("net_%s_ip", intf
);
874 grub_env_set (buf
, val
);
882 defmac_get_env (struct grub_env_var
*var
__attribute__ ((unused
)),
883 const char *val
__attribute__ ((unused
)))
885 const char *intf
= grub_env_get ("net_default_interface");
886 const char *ret
= NULL
;
889 char *buf
= grub_xasprintf ("net_%s_mac", intf
);
891 ret
= grub_env_get (buf
);
898 defmac_set_env (struct grub_env_var
*var
__attribute__ ((unused
)),
901 const char *intf
= grub_env_get ("net_default_interface");
904 char *buf
= grub_xasprintf ("net_%s_mac", intf
);
906 grub_env_set (buf
, val
);
914 grub_net_network_level_interface_register (struct grub_net_network_level_interface
*inter
)
917 char buf
[GRUB_NET_MAX_STR_HWADDR_LEN
];
920 grub_net_hwaddr_to_str (&inter
->hwaddress
, buf
);
921 name
= grub_xasprintf ("net_%s_mac", inter
->name
);
924 for (ptr
= name
; *ptr
; ptr
++)
927 grub_env_set (name
, buf
);
928 grub_register_variable_hook (name
, 0, hwaddr_set_env
);
929 grub_env_export (name
);
934 char buf
[GRUB_NET_MAX_STR_ADDR_LEN
];
937 grub_net_addr_to_str (&inter
->address
, buf
);
938 name
= grub_xasprintf ("net_%s_ip", inter
->name
);
941 for (ptr
= name
; *ptr
; ptr
++)
944 grub_env_set (name
, buf
);
945 grub_register_variable_hook (name
, 0, addr_set_env
);
946 grub_env_export (name
);
950 inter
->card
->num_ifaces
++;
951 inter
->prev
= &grub_net_network_level_interfaces
;
952 inter
->next
= grub_net_network_level_interfaces
;
954 inter
->next
->prev
= &inter
->next
;
955 grub_net_network_level_interfaces
= inter
;
960 grub_net_add_ipv4_local (struct grub_net_network_level_interface
*inter
,
963 grub_uint32_t ip_cpu
;
964 struct grub_net_route
*route
;
966 if (inter
->address
.type
!= GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
)
969 ip_cpu
= grub_be_to_cpu32 (inter
->address
.ipv4
);
973 if (!(ip_cpu
& 0x80000000))
975 else if (!(ip_cpu
& 0x40000000))
977 else if (!(ip_cpu
& 0x20000000))
983 route
= grub_zalloc (sizeof (*route
));
987 route
->name
= grub_xasprintf ("%s:local", inter
->name
);
994 route
->target
.type
= GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
;
995 route
->target
.ipv4
.base
= grub_cpu_to_be32 (ip_cpu
& (0xffffffff << (32 - mask
)));
996 route
->target
.ipv4
.masksize
= mask
;
997 route
->is_gateway
= 0;
998 route
->interface
= inter
;
1000 grub_net_route_register (route
);
1005 /* FIXME: support MAC specifying. */
1007 grub_cmd_addaddr (struct grub_command
*cmd
__attribute__ ((unused
)),
1008 int argc
, char **args
)
1010 struct grub_net_card
*card
;
1011 grub_net_network_level_address_t addr
;
1013 grub_net_interface_flags_t flags
= 0;
1014 struct grub_net_network_level_interface
*inf
;
1017 return grub_error (GRUB_ERR_BAD_ARGUMENT
, N_("three arguments expected"));
1019 FOR_NET_CARDS (card
)
1020 if (grub_strcmp (card
->name
, args
[1]) == 0)
1023 return grub_error (GRUB_ERR_BAD_ARGUMENT
, N_("card not found"));
1025 err
= grub_net_resolve_address (args
[2], &addr
);
1029 if (card
->flags
& GRUB_NET_CARD_NO_MANUAL_INTERFACES
)
1030 return grub_error (GRUB_ERR_IO
,
1031 "this card doesn't support address addition");
1033 if (card
->flags
& GRUB_NET_CARD_HWADDRESS_IMMUTABLE
)
1034 flags
|= GRUB_NET_INTERFACE_HWADDRESS_IMMUTABLE
;
1036 inf
= grub_net_add_addr (args
[0], card
, &addr
, &card
->default_address
,
1039 grub_net_add_ipv4_local (inf
, -1);
1045 grub_cmd_delroute (struct grub_command
*cmd
__attribute__ ((unused
)),
1046 int argc
, char **args
)
1048 struct grub_net_route
*route
;
1049 struct grub_net_route
**prev
;
1052 return grub_error (GRUB_ERR_BAD_ARGUMENT
, N_("one argument expected"));
1054 for (prev
= &grub_net_routes
, route
= *prev
; route
; prev
= &((*prev
)->next
),
1056 if (grub_strcmp (route
->name
, args
[0]) == 0)
1058 *prev
= route
->next
;
1059 grub_free (route
->name
);
1065 return GRUB_ERR_NONE
;
1069 grub_net_add_route (const char *name
,
1070 grub_net_network_level_netaddress_t target
,
1071 struct grub_net_network_level_interface
*inter
)
1073 struct grub_net_route
*route
;
1075 route
= grub_zalloc (sizeof (*route
));
1079 route
->name
= grub_strdup (name
);
1086 route
->target
= target
;
1087 route
->is_gateway
= 0;
1088 route
->interface
= inter
;
1090 grub_net_route_register (route
);
1092 return GRUB_ERR_NONE
;
1096 grub_net_add_route_gw (const char *name
,
1097 grub_net_network_level_netaddress_t target
,
1098 grub_net_network_level_address_t gw
,
1099 struct grub_net_network_level_interface
*inter
)
1101 struct grub_net_route
*route
;
1103 route
= grub_zalloc (sizeof (*route
));
1107 route
->name
= grub_strdup (name
);
1114 route
->target
= target
;
1115 route
->is_gateway
= 1;
1117 route
->interface
= inter
;
1119 grub_net_route_register (route
);
1121 return GRUB_ERR_NONE
;
1125 grub_cmd_addroute (struct grub_command
*cmd
__attribute__ ((unused
)),
1126 int argc
, char **args
)
1128 grub_net_network_level_netaddress_t target
;
1130 return grub_error (GRUB_ERR_BAD_ARGUMENT
,
1131 N_("three arguments expected"));
1133 grub_net_resolve_net_address (args
[1], &target
);
1135 if (grub_strcmp (args
[2], "gw") == 0 && argc
>= 4)
1138 grub_net_network_level_address_t gw
;
1140 err
= grub_net_resolve_address (args
[3], &gw
);
1143 return grub_net_add_route_gw (args
[0], target
, gw
, NULL
);
1147 struct grub_net_network_level_interface
*inter
;
1149 FOR_NET_NETWORK_LEVEL_INTERFACES (inter
)
1150 if (grub_strcmp (inter
->name
, args
[2]) == 0)
1154 return grub_error (GRUB_ERR_BAD_ARGUMENT
,
1155 N_("unrecognised network interface `%s'"), args
[2]);
1156 return grub_net_add_route (args
[0], target
, inter
);
1161 print_net_address (const grub_net_network_level_netaddress_t
*target
)
1163 switch (target
->type
)
1165 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV
:
1166 /* TRANSLATORS: it refers to the network address. */
1167 grub_printf ("%s\n", _("temporary"));
1169 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
:
1171 grub_uint32_t n
= grub_be_to_cpu32 (target
->ipv4
.base
);
1172 grub_printf ("%d.%d.%d.%d/%d ", ((n
>> 24) & 0xff),
1176 target
->ipv4
.masksize
);
1179 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
:
1181 char buf
[GRUB_NET_MAX_STR_ADDR_LEN
];
1182 struct grub_net_network_level_address base
;
1183 base
.type
= GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
;
1184 grub_memcpy (&base
.ipv6
, &target
->ipv6
, 16);
1185 grub_net_addr_to_str (&base
, buf
);
1186 grub_printf ("%s/%d ", buf
, target
->ipv6
.masksize
);
1190 grub_printf (_("Unknown address type %d\n"), target
->type
);
1194 print_address (const grub_net_network_level_address_t
*target
)
1196 char buf
[GRUB_NET_MAX_STR_ADDR_LEN
];
1197 grub_net_addr_to_str (target
, buf
);
1202 grub_cmd_listroutes (struct grub_command
*cmd
__attribute__ ((unused
)),
1203 int argc
__attribute__ ((unused
)),
1204 char **args
__attribute__ ((unused
)))
1206 struct grub_net_route
*route
;
1207 FOR_NET_ROUTES(route
)
1209 grub_printf ("%s ", route
->name
);
1210 print_net_address (&route
->target
);
1211 if (route
->is_gateway
)
1213 grub_printf ("gw ");
1214 print_address (&route
->gw
);
1217 grub_printf ("%s", route
->interface
->name
);
1220 return GRUB_ERR_NONE
;
1224 grub_cmd_listcards (struct grub_command
*cmd
__attribute__ ((unused
)),
1225 int argc
__attribute__ ((unused
)),
1226 char **args
__attribute__ ((unused
)))
1228 struct grub_net_card
*card
;
1231 char buf
[GRUB_NET_MAX_STR_HWADDR_LEN
];
1232 grub_net_hwaddr_to_str (&card
->default_address
, buf
);
1233 grub_printf ("%s %s\n", card
->name
, buf
);
1235 return GRUB_ERR_NONE
;
1239 grub_cmd_listaddrs (struct grub_command
*cmd
__attribute__ ((unused
)),
1240 int argc
__attribute__ ((unused
)),
1241 char **args
__attribute__ ((unused
)))
1243 struct grub_net_network_level_interface
*inf
;
1244 FOR_NET_NETWORK_LEVEL_INTERFACES (inf
)
1246 char bufh
[GRUB_NET_MAX_STR_HWADDR_LEN
];
1247 char bufn
[GRUB_NET_MAX_STR_ADDR_LEN
];
1248 grub_net_hwaddr_to_str (&inf
->hwaddress
, bufh
);
1249 grub_net_addr_to_str (&inf
->address
, bufn
);
1250 grub_printf ("%s %s %s\n", inf
->name
, bufh
, bufn
);
1252 return GRUB_ERR_NONE
;
1255 grub_net_app_level_t grub_net_app_level_list
;
1256 struct grub_net_socket
*grub_net_sockets
;
1259 grub_net_open_real (const char *name
)
1261 grub_net_app_level_t proto
;
1262 const char *protname
, *server
;
1263 grub_size_t protnamelen
;
1266 if (grub_strncmp (name
, "pxe:", sizeof ("pxe:") - 1) == 0)
1269 protnamelen
= sizeof ("tftp") - 1;
1270 server
= name
+ sizeof ("pxe:") - 1;
1272 else if (grub_strcmp (name
, "pxe") == 0)
1275 protnamelen
= sizeof ("tftp") - 1;
1276 server
= grub_net_default_server
;
1281 comma
= grub_strchr (name
, ',');
1284 protnamelen
= comma
- name
;
1290 protnamelen
= grub_strlen (name
);
1291 server
= grub_net_default_server
;
1297 grub_error (GRUB_ERR_NET_BAD_ADDRESS
,
1298 N_("no server is specified"));
1302 for (try = 0; try < 2; try++)
1304 FOR_NET_APP_LEVEL (proto
)
1306 if (grub_memcmp (proto
->name
, protname
, protnamelen
) == 0
1307 && proto
->name
[protnamelen
] == 0)
1309 grub_net_t ret
= grub_zalloc (sizeof (*ret
));
1312 ret
->protocol
= proto
;
1313 ret
->server
= grub_strdup (server
);
1319 ret
->fs
= &grub_net_fs
;
1325 const char *prefix
, *root
;
1326 char *prefdev
, *comma
;
1330 /* Do not attempt to load module if it requires protocol provided
1331 by this module - it results in infinite recursion. Just continue,
1332 fail and cleanup on next iteration.
1334 prefix
= grub_env_get ("prefix");
1338 prefdev
= grub_file_get_device_name (prefix
);
1341 root
= grub_env_get ("root");
1344 prefdev
= grub_strdup (root
);
1349 if (grub_strncmp (prefdev
, "pxe", sizeof ("pxe") - 1) == 0 &&
1350 (!prefdev
[sizeof ("pxe") - 1] || (prefdev
[sizeof("pxe") - 1] == ':')))
1352 grub_free (prefdev
);
1353 prefdev
= grub_strdup ("tftp");
1358 comma
= grub_strchr (prefdev
, ',');
1361 devlen
= grub_strlen (prefdev
);
1363 if (protnamelen
== devlen
&& grub_memcmp (prefdev
, protname
, devlen
) == 0)
1366 grub_free (prefdev
);
1371 if (sizeof ("http") - 1 == protnamelen
1372 && grub_memcmp ("http", protname
, protnamelen
) == 0)
1374 grub_dl_load ("http");
1375 grub_errno
= GRUB_ERR_NONE
;
1378 if (sizeof ("tftp") - 1 == protnamelen
1379 && grub_memcmp ("tftp", protname
, protnamelen
) == 0)
1381 grub_dl_load ("tftp");
1382 grub_errno
= GRUB_ERR_NONE
;
1389 /* Restore original error. */
1390 grub_error (GRUB_ERR_UNKNOWN_DEVICE
, N_("disk `%s' not found"),
1397 grub_net_fs_dir (grub_device_t device
, const char *path
__attribute__ ((unused
)),
1398 grub_fs_dir_hook_t hook
__attribute__ ((unused
)),
1399 void *hook_data
__attribute__ ((unused
)))
1402 return grub_error (GRUB_ERR_BUG
, "invalid net device");
1403 return GRUB_ERR_NONE
;
1407 grub_net_fs_open (struct grub_file
*file_out
, const char *name
)
1410 struct grub_file
*file
, *bufio
;
1412 file
= grub_malloc (sizeof (*file
));
1416 grub_memcpy (file
, file_out
, sizeof (struct grub_file
));
1417 file
->device
->net
->packs
.first
= NULL
;
1418 file
->device
->net
->packs
.last
= NULL
;
1419 file
->device
->net
->name
= grub_strdup (name
);
1420 if (!file
->device
->net
->name
)
1426 err
= file
->device
->net
->protocol
->open (file
, name
);
1429 while (file
->device
->net
->packs
.first
)
1431 grub_netbuff_free (file
->device
->net
->packs
.first
->nb
);
1432 grub_net_remove_packet (file
->device
->net
->packs
.first
);
1434 grub_free (file
->device
->net
->name
);
1438 bufio
= grub_bufio_open (file
, 32768);
1441 while (file
->device
->net
->packs
.first
)
1443 grub_netbuff_free (file
->device
->net
->packs
.first
->nb
);
1444 grub_net_remove_packet (file
->device
->net
->packs
.first
);
1446 file
->device
->net
->protocol
->close (file
);
1447 grub_free (file
->device
->net
->name
);
1452 grub_memcpy (file_out
, bufio
, sizeof (struct grub_file
));
1454 return GRUB_ERR_NONE
;
1458 grub_net_fs_close (grub_file_t file
)
1460 while (file
->device
->net
->packs
.first
)
1462 grub_netbuff_free (file
->device
->net
->packs
.first
->nb
);
1463 grub_net_remove_packet (file
->device
->net
->packs
.first
);
1465 file
->device
->net
->protocol
->close (file
);
1466 grub_free (file
->device
->net
->name
);
1467 return GRUB_ERR_NONE
;
1471 receive_packets (struct grub_net_card
*card
, int *stop_condition
)
1474 if (card
->num_ifaces
== 0)
1478 grub_err_t err
= GRUB_ERR_NONE
;
1479 if (card
->driver
->open
)
1480 err
= card
->driver
->open (card
);
1483 grub_errno
= GRUB_ERR_NONE
;
1488 while (received
< 100)
1490 /* Maybe should be better have a fixed number of packets for each card
1491 and just mark them as used and not used. */
1492 struct grub_net_buff
*nb
;
1494 if (received
> 10 && stop_condition
&& *stop_condition
)
1497 nb
= card
->driver
->recv (card
);
1500 card
->last_poll
= grub_get_time_ms ();
1504 grub_net_recv_ethernet_packet (nb
, card
);
1507 grub_dprintf ("net", "error receiving: %d: %s\n", grub_errno
,
1509 grub_errno
= GRUB_ERR_NONE
;
1512 grub_print_error ();
1516 grub_env_write_readonly (struct grub_env_var
*var
__attribute__ ((unused
)),
1517 const char *val
__attribute__ ((unused
)))
1523 grub_env_set_net_property (const char *intername
, const char *suffix
,
1524 const char *value
, grub_size_t len
)
1526 char *varname
, *varvalue
;
1529 varname
= grub_xasprintf ("net_%s_%s", intername
, suffix
);
1532 for (ptr
= varname
; *ptr
; ptr
++)
1535 varvalue
= grub_malloc (len
+ 1);
1538 grub_free (varname
);
1542 grub_memcpy (varvalue
, value
, len
);
1544 grub_err_t ret
= grub_env_set (varname
, varvalue
);
1545 grub_register_variable_hook (varname
, 0, grub_env_write_readonly
);
1546 grub_env_export (varname
);
1547 grub_free (varname
);
1548 grub_free (varvalue
);
1554 grub_net_poll_cards (unsigned time
, int *stop_condition
)
1556 struct grub_net_card
*card
;
1557 grub_uint64_t start_time
;
1558 start_time
= grub_get_time_ms ();
1559 while ((grub_get_time_ms () - start_time
) < time
1560 && (!stop_condition
|| !*stop_condition
))
1561 FOR_NET_CARDS (card
)
1562 receive_packets (card
, stop_condition
);
1563 grub_net_tcp_retransmit ();
1567 grub_net_poll_cards_idle_real (void)
1569 struct grub_net_card
*card
;
1570 FOR_NET_CARDS (card
)
1572 grub_uint64_t ctime
= grub_get_time_ms ();
1574 if (ctime
< card
->last_poll
1575 || ctime
>= card
->last_poll
+ card
->idle_poll_delay_ms
)
1576 receive_packets (card
, 0);
1578 grub_net_tcp_retransmit ();
1581 /* Read from the packets list*/
1583 grub_net_fs_read_real (grub_file_t file
, char *buf
, grub_size_t len
)
1585 grub_net_t net
= file
->device
->net
;
1586 struct grub_net_buff
*nb
;
1588 grub_size_t amount
, total
= 0;
1591 while (try <= GRUB_NET_TRIES
)
1593 while (net
->packs
.first
)
1596 nb
= net
->packs
.first
->nb
;
1597 amount
= nb
->tail
- nb
->data
;
1602 file
->device
->net
->offset
+= amount
;
1603 if (grub_file_progress_hook
)
1604 grub_file_progress_hook (0, 0, amount
, file
);
1607 grub_memcpy (ptr
, nb
->data
, amount
);
1610 if (amount
== (grub_size_t
) (nb
->tail
- nb
->data
))
1612 grub_netbuff_free (nb
);
1613 grub_net_remove_packet (net
->packs
.first
);
1620 if (net
->protocol
->packets_pulled
)
1621 net
->protocol
->packets_pulled (file
);
1625 if (net
->protocol
->packets_pulled
)
1626 net
->protocol
->packets_pulled (file
);
1631 grub_net_poll_cards (GRUB_NET_INTERVAL
+
1632 (try * GRUB_NET_INTERVAL_ADDITION
), &net
->stall
);
1637 grub_error (GRUB_ERR_TIMEOUT
, N_("timeout reading `%s'"), net
->name
);
1642 have_ahead (struct grub_file
*file
)
1644 grub_net_t net
= file
->device
->net
;
1645 grub_off_t ret
= net
->offset
;
1646 struct grub_net_packet
*pack
;
1647 for (pack
= net
->packs
.first
; pack
; pack
= pack
->next
)
1648 ret
+= pack
->nb
->tail
- pack
->nb
->data
;
1653 grub_net_seek_real (struct grub_file
*file
, grub_off_t offset
)
1655 if (offset
== file
->device
->net
->offset
)
1656 return GRUB_ERR_NONE
;
1658 if (offset
> file
->device
->net
->offset
)
1660 if (!file
->device
->net
->protocol
->seek
|| have_ahead (file
) >= offset
)
1662 grub_net_fs_read_real (file
, NULL
,
1663 offset
- file
->device
->net
->offset
);
1666 return file
->device
->net
->protocol
->seek (file
, offset
);
1671 if (file
->device
->net
->protocol
->seek
)
1672 return file
->device
->net
->protocol
->seek (file
, offset
);
1673 while (file
->device
->net
->packs
.first
)
1675 grub_netbuff_free (file
->device
->net
->packs
.first
->nb
);
1676 grub_net_remove_packet (file
->device
->net
->packs
.first
);
1678 file
->device
->net
->protocol
->close (file
);
1680 file
->device
->net
->packs
.first
= NULL
;
1681 file
->device
->net
->packs
.last
= NULL
;
1682 file
->device
->net
->offset
= 0;
1683 file
->device
->net
->eof
= 0;
1684 file
->device
->net
->stall
= 0;
1685 err
= file
->device
->net
->protocol
->open (file
, file
->device
->net
->name
);
1688 grub_net_fs_read_real (file
, NULL
, offset
);
1694 grub_net_fs_read (grub_file_t file
, char *buf
, grub_size_t len
)
1696 if (file
->offset
!= file
->device
->net
->offset
)
1699 err
= grub_net_seek_real (file
, file
->offset
);
1703 return grub_net_fs_read_real (file
, buf
, len
);
1706 static struct grub_fs grub_net_fs
=
1709 .dir
= grub_net_fs_dir
,
1710 .open
= grub_net_fs_open
,
1711 .read
= grub_net_fs_read
,
1712 .close
= grub_net_fs_close
,
1719 grub_net_fini_hw (int noreturn
__attribute__ ((unused
)))
1721 struct grub_net_card
*card
;
1722 FOR_NET_CARDS (card
)
1725 if (card
->driver
->close
)
1726 card
->driver
->close (card
);
1729 return GRUB_ERR_NONE
;
1733 grub_net_restore_hw (void)
1735 return GRUB_ERR_NONE
;
1738 static struct grub_preboot
*fini_hnd
;
1740 static grub_command_t cmd_addaddr
, cmd_deladdr
, cmd_addroute
, cmd_delroute
;
1741 static grub_command_t cmd_lsroutes
, cmd_lscards
;
1742 static grub_command_t cmd_lsaddr
, cmd_slaac
;
1746 grub_register_variable_hook ("net_default_server", defserver_get_env
,
1748 grub_env_export ("net_default_server");
1749 grub_register_variable_hook ("pxe_default_server", defserver_get_env
,
1751 grub_env_export ("pxe_default_server");
1752 grub_register_variable_hook ("net_default_ip", defip_get_env
,
1754 grub_env_export ("net_default_ip");
1755 grub_register_variable_hook ("net_default_mac", defmac_get_env
,
1757 grub_env_export ("net_default_mac");
1759 cmd_addaddr
= grub_register_command ("net_add_addr", grub_cmd_addaddr
,
1760 /* TRANSLATORS: HWADDRESS stands for
1761 "hardware address". */
1762 N_("SHORTNAME CARD ADDRESS [HWADDRESS]"),
1763 N_("Add a network address."));
1764 cmd_slaac
= grub_register_command ("net_ipv6_autoconf",
1765 grub_cmd_ipv6_autoconf
,
1766 N_("[CARD [HWADDRESS]]"),
1767 N_("Perform an IPV6 autoconfiguration"));
1769 cmd_deladdr
= grub_register_command ("net_del_addr", grub_cmd_deladdr
,
1771 N_("Delete a network address."));
1772 cmd_addroute
= grub_register_command ("net_add_route", grub_cmd_addroute
,
1773 /* TRANSLATORS: "gw" is a keyword. */
1774 N_("SHORTNAME NET [INTERFACE| gw GATEWAY]"),
1775 N_("Add a network route."));
1776 cmd_delroute
= grub_register_command ("net_del_route", grub_cmd_delroute
,
1778 N_("Delete a network route."));
1779 cmd_lsroutes
= grub_register_command ("net_ls_routes", grub_cmd_listroutes
,
1780 "", N_("list network routes"));
1781 cmd_lscards
= grub_register_command ("net_ls_cards", grub_cmd_listcards
,
1782 "", N_("list network cards"));
1783 cmd_lsaddr
= grub_register_command ("net_ls_addr", grub_cmd_listaddrs
,
1784 "", N_("list network addresses"));
1788 grub_net_open
= grub_net_open_real
;
1789 fini_hnd
= grub_loader_register_preboot_hook (grub_net_fini_hw
,
1790 grub_net_restore_hw
,
1791 GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK
);
1792 grub_net_poll_cards_idle
= grub_net_poll_cards_idle_real
;
1797 grub_register_variable_hook ("net_default_server", 0, 0);
1798 grub_register_variable_hook ("pxe_default_server", 0, 0);
1802 grub_unregister_command (cmd_addaddr
);
1803 grub_unregister_command (cmd_deladdr
);
1804 grub_unregister_command (cmd_addroute
);
1805 grub_unregister_command (cmd_delroute
);
1806 grub_unregister_command (cmd_lsroutes
);
1807 grub_unregister_command (cmd_lscards
);
1808 grub_unregister_command (cmd_lsaddr
);
1809 grub_unregister_command (cmd_slaac
);
1810 grub_fs_unregister (&grub_net_fs
);
1811 grub_net_open
= NULL
;
1812 grub_net_fini_hw (0);
1813 grub_loader_unregister_preboot_hook (fini_hnd
);
1814 grub_net_poll_cards_idle
= grub_net_poll_cards_idle_real
;