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
;
42 struct grub_net_route
*next
;
43 struct grub_net_route
**prev
;
44 grub_net_network_level_netaddress_t target
;
46 struct grub_net_network_level_protocol
*prot
;
50 struct grub_net_network_level_interface
*interface
;
51 grub_net_network_level_address_t gw
;
55 struct grub_net_route
*grub_net_routes
= NULL
;
56 struct grub_net_network_level_interface
*grub_net_network_level_interfaces
= NULL
;
57 struct grub_net_card
*grub_net_cards
= NULL
;
58 struct grub_net_network_level_protocol
*grub_net_network_level_protocols
= NULL
;
59 static struct grub_fs grub_net_fs
;
61 struct grub_net_link_layer_entry
{
63 grub_net_network_level_address_t nl_address
;
64 grub_net_link_level_address_t ll_address
;
67 #define LINK_LAYER_CACHE_SIZE 256
69 static struct grub_net_link_layer_entry
*
70 link_layer_find_entry (const grub_net_network_level_address_t
*proto
,
71 const struct grub_net_card
*card
)
74 if (!card
->link_layer_table
)
76 for (i
= 0; i
< LINK_LAYER_CACHE_SIZE
; i
++)
78 if (card
->link_layer_table
[i
].avail
== 1
79 && grub_net_addr_cmp (&card
->link_layer_table
[i
].nl_address
,
81 return &card
->link_layer_table
[i
];
87 grub_net_link_layer_add_address (struct grub_net_card
*card
,
88 const grub_net_network_level_address_t
*nl
,
89 const grub_net_link_level_address_t
*ll
,
92 struct grub_net_link_layer_entry
*entry
;
94 /* Check if the sender is in the cache table. */
95 entry
= link_layer_find_entry (nl
, card
);
96 /* Update sender hardware address. */
97 if (entry
&& override
)
98 grub_memcpy (&entry
->ll_address
, ll
, sizeof (entry
->ll_address
));
102 /* Add sender to cache table. */
103 if (card
->link_layer_table
== NULL
)
104 card
->link_layer_table
= grub_zalloc (LINK_LAYER_CACHE_SIZE
105 * sizeof (card
->link_layer_table
[0]));
106 entry
= &(card
->link_layer_table
[card
->new_ll_entry
]);
108 grub_memcpy (&entry
->ll_address
, ll
, sizeof (entry
->ll_address
));
109 grub_memcpy (&entry
->nl_address
, nl
, sizeof (entry
->nl_address
));
110 card
->new_ll_entry
++;
111 if (card
->new_ll_entry
== LINK_LAYER_CACHE_SIZE
)
112 card
->new_ll_entry
= 0;
116 grub_net_link_layer_resolve_check (struct grub_net_network_level_interface
*inf
,
117 const grub_net_network_level_address_t
*proto_addr
)
119 struct grub_net_link_layer_entry
*entry
;
121 if (proto_addr
->type
== GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
122 && proto_addr
->ipv4
== 0xffffffff)
124 entry
= link_layer_find_entry (proto_addr
, inf
->card
);
131 grub_net_link_layer_resolve (struct grub_net_network_level_interface
*inf
,
132 const grub_net_network_level_address_t
*proto_addr
,
133 grub_net_link_level_address_t
*hw_addr
)
135 struct grub_net_link_layer_entry
*entry
;
138 if ((proto_addr
->type
== GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
139 && proto_addr
->ipv4
== 0xffffffff)
140 || proto_addr
->type
== GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV
141 || (proto_addr
->type
== GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
142 && proto_addr
->ipv6
[0] == grub_be_to_cpu64_compile_time (0xff02ULL
144 && proto_addr
->ipv6
[1] == (grub_be_to_cpu64_compile_time (1))))
146 hw_addr
->type
= GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET
;
147 grub_memset (hw_addr
->mac
, -1, 6);
148 return GRUB_ERR_NONE
;
151 if (proto_addr
->type
== GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
152 && ((grub_be_to_cpu64 (proto_addr
->ipv6
[0]) >> 56) == 0xff))
154 hw_addr
->type
= GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET
;
155 hw_addr
->mac
[0] = 0x33;
156 hw_addr
->mac
[1] = 0x33;
157 hw_addr
->mac
[2] = ((grub_be_to_cpu64 (proto_addr
->ipv6
[1]) >> 24) & 0xff);
158 hw_addr
->mac
[3] = ((grub_be_to_cpu64 (proto_addr
->ipv6
[1]) >> 16) & 0xff);
159 hw_addr
->mac
[4] = ((grub_be_to_cpu64 (proto_addr
->ipv6
[1]) >> 8) & 0xff);
160 hw_addr
->mac
[5] = ((grub_be_to_cpu64 (proto_addr
->ipv6
[1]) >> 0) & 0xff);
161 return GRUB_ERR_NONE
;
164 /* Check cache table. */
165 entry
= link_layer_find_entry (proto_addr
, inf
->card
);
168 *hw_addr
= entry
->ll_address
;
169 return GRUB_ERR_NONE
;
171 switch (proto_addr
->type
)
173 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
:
174 err
= grub_net_arp_send_request (inf
, proto_addr
);
176 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
:
177 err
= grub_net_icmp6_send_request (inf
, proto_addr
);
179 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV
:
180 return grub_error (GRUB_ERR_BUG
, "shouldn't reach here");
182 return grub_error (GRUB_ERR_BUG
,
183 "unsupported address type %d", proto_addr
->type
);
187 entry
= link_layer_find_entry (proto_addr
, inf
->card
);
190 *hw_addr
= entry
->ll_address
;
191 return GRUB_ERR_NONE
;
193 return grub_error (GRUB_ERR_TIMEOUT
,
194 N_("timeout: could not resolve hardware address"));
198 grub_net_card_unregister (struct grub_net_card
*card
)
200 struct grub_net_network_level_interface
*inf
, *next
;
201 FOR_NET_NETWORK_LEVEL_INTERFACES_SAFE(inf
, next
)
202 if (inf
->card
== card
)
203 grub_net_network_level_interface_unregister (inf
);
206 if (card
->driver
->close
)
207 card
->driver
->close (card
);
210 grub_list_remove (GRUB_AS_LIST (card
));
213 static struct grub_net_slaac_mac_list
*
214 grub_net_ipv6_get_slaac (struct grub_net_card
*card
,
215 const grub_net_link_level_address_t
*hwaddr
)
217 struct grub_net_slaac_mac_list
*slaac
;
220 for (slaac
= card
->slaac_list
; slaac
; slaac
= slaac
->next
)
221 if (grub_net_hwaddr_cmp (&slaac
->address
, hwaddr
) == 0)
224 slaac
= grub_zalloc (sizeof (*slaac
));
228 slaac
->name
= grub_malloc (grub_strlen (card
->name
)
229 + GRUB_NET_MAX_STR_HWADDR_LEN
230 + sizeof (":slaac"));
231 ptr
= grub_stpcpy (slaac
->name
, card
->name
);
232 if (grub_net_hwaddr_cmp (&card
->default_address
, hwaddr
) != 0)
234 ptr
= grub_stpcpy (ptr
, ":");
235 grub_net_hwaddr_to_str (hwaddr
, ptr
);
236 ptr
+= grub_strlen (ptr
);
238 ptr
= grub_stpcpy (ptr
, ":slaac");
240 grub_memcpy (&slaac
->address
, hwaddr
, sizeof (slaac
->address
));
241 slaac
->next
= card
->slaac_list
;
242 card
->slaac_list
= slaac
;
247 grub_net_network_level_interface_register (struct grub_net_network_level_interface
*inter
);
249 static struct grub_net_network_level_interface
*
250 grub_net_add_addr_real (char *name
,
251 struct grub_net_card
*card
,
252 const grub_net_network_level_address_t
*addr
,
253 const grub_net_link_level_address_t
*hwaddress
,
254 grub_net_interface_flags_t flags
)
256 struct grub_net_network_level_interface
*inter
;
258 inter
= grub_zalloc (sizeof (*inter
));
263 grub_memcpy (&(inter
->address
), addr
, sizeof (inter
->address
));
264 grub_memcpy (&(inter
->hwaddress
), hwaddress
, sizeof (inter
->hwaddress
));
265 inter
->flags
= flags
;
267 inter
->dhcp_ack
= NULL
;
268 inter
->dhcp_acklen
= 0;
270 grub_net_network_level_interface_register (inter
);
275 struct grub_net_network_level_interface
*
276 grub_net_add_addr (const char *name
,
277 struct grub_net_card
*card
,
278 const grub_net_network_level_address_t
*addr
,
279 const grub_net_link_level_address_t
*hwaddress
,
280 grub_net_interface_flags_t flags
)
282 char *name_dup
= grub_strdup (name
);
283 struct grub_net_network_level_interface
*ret
;
287 ret
= grub_net_add_addr_real (name_dup
, card
, addr
, hwaddress
, flags
);
289 grub_free (name_dup
);
293 struct grub_net_network_level_interface
*
294 grub_net_ipv6_get_link_local (struct grub_net_card
*card
,
295 const grub_net_link_level_address_t
*hwaddr
)
297 struct grub_net_network_level_interface
*inf
;
300 grub_net_network_level_address_t addr
;
302 name
= grub_malloc (grub_strlen (card
->name
)
303 + GRUB_NET_MAX_STR_HWADDR_LEN
308 addr
.type
= GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
;
309 addr
.ipv6
[0] = grub_cpu_to_be64 (0xfe80ULL
<< 48);
310 addr
.ipv6
[1] = grub_net_ipv6_get_id (hwaddr
);
312 FOR_NET_NETWORK_LEVEL_INTERFACES (inf
)
314 if (inf
->card
== card
315 && grub_net_hwaddr_cmp (&inf
->hwaddress
, hwaddr
) == 0
316 && grub_net_addr_cmp (&inf
->address
, &addr
) == 0)
320 ptr
= grub_stpcpy (name
, card
->name
);
321 if (grub_net_hwaddr_cmp (&card
->default_address
, hwaddr
) != 0)
323 ptr
= grub_stpcpy (ptr
, ":");
324 grub_net_hwaddr_to_str (hwaddr
, ptr
);
325 ptr
+= grub_strlen (ptr
);
327 ptr
= grub_stpcpy (ptr
, ":link");
328 return grub_net_add_addr_real (name
, card
, &addr
, hwaddr
, 0);
331 /* FIXME: allow to specify mac address. */
333 grub_cmd_ipv6_autoconf (struct grub_command
*cmd
__attribute__ ((unused
)),
334 int argc
, char **args
)
336 struct grub_net_card
*card
;
337 struct grub_net_network_level_interface
**ifaces
;
338 grub_size_t ncards
= 0;
342 struct grub_net_slaac_mac_list
**slaacs
;
346 if (argc
> 0 && grub_strcmp (card
->name
, args
[0]) != 0)
351 ifaces
= grub_zalloc (ncards
* sizeof (ifaces
[0]));
352 slaacs
= grub_zalloc (ncards
* sizeof (slaacs
[0]));
353 if (!ifaces
|| !slaacs
)
362 if (argc
> 0 && grub_strcmp (card
->name
, args
[0]) != 0)
364 ifaces
[j
] = grub_net_ipv6_get_link_local (card
, &card
->default_address
);
371 slaacs
[j
] = grub_net_ipv6_get_slaac (card
, &card
->default_address
);
381 for (interval
= 200; interval
< 10000; interval
*= 2)
383 /* FIXME: send router solicitation. */
385 for (j
= 0; j
< ncards
; j
++)
387 if (slaacs
[j
]->slaac_counter
)
393 grub_net_poll_cards (interval
, 0);
397 for (j
= 0; j
< ncards
; j
++)
399 if (slaacs
[j
]->slaac_counter
)
401 err
= grub_error (GRUB_ERR_FILE_NOT_FOUND
,
402 N_("couldn't autoconfigure %s"),
403 ifaces
[j
]->card
->name
);
412 grub_net_route_register (struct grub_net_route
*route
)
414 grub_list_push (GRUB_AS_LIST_P (&grub_net_routes
),
415 GRUB_AS_LIST (route
));
418 #define FOR_NET_ROUTES(var) for (var = grub_net_routes; var; var = var->next)
421 parse_ip (const char *val
, grub_uint32_t
*ip
, const char **rest
)
423 grub_uint32_t newip
= 0;
425 const char *ptr
= val
;
427 for (i
= 0; i
< 4; i
++)
430 t
= grub_strtoul (ptr
, (char **) &ptr
, 0);
433 grub_errno
= GRUB_ERR_NONE
;
436 if (*ptr
!= '.' && i
== 0)
445 if (i
!= 3 && *ptr
!= '.')
449 *ip
= grub_cpu_to_le32 (newip
);
456 parse_ip6 (const char *val
, grub_uint64_t
*ip
, const char **rest
)
458 grub_uint16_t newip
[8];
459 const char *ptr
= val
;
460 int word
, quaddot
= -1;
462 if (ptr
[0] == ':' && ptr
[1] != ':')
467 for (word
= 0; word
< 8; word
++)
477 t
= grub_strtoul (ptr
, (char **) &ptr
, 16);
480 grub_errno
= GRUB_ERR_NONE
;
485 newip
[word
] = grub_cpu_to_be16 (t
);
490 if (quaddot
== -1 && word
< 7)
494 grub_memmove (&newip
[quaddot
+ 7 - word
], &newip
[quaddot
],
495 (word
- quaddot
+ 1) * sizeof (newip
[0]));
496 grub_memset (&newip
[quaddot
], 0, (7 - word
) * sizeof (newip
[0]));
498 grub_memcpy (ip
, newip
, 16);
505 match_net (const grub_net_network_level_netaddress_t
*net
,
506 const grub_net_network_level_address_t
*addr
)
508 if (net
->type
!= addr
->type
)
512 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV
:
514 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
:
516 grub_uint32_t mask
= (0xffffffffU
<< (32 - net
->ipv4
.masksize
));
517 if (net
->ipv4
.masksize
== 0)
519 return ((grub_be_to_cpu32 (net
->ipv4
.base
) & mask
)
520 == (grub_be_to_cpu32 (addr
->ipv4
) & mask
));
522 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
:
524 grub_uint64_t mask
[2];
525 if (net
->ipv6
.masksize
<= 64)
527 mask
[0] = 0xffffffffffffffffULL
<< (64 - net
->ipv6
.masksize
);
532 mask
[0] = 0xffffffffffffffffULL
;
533 mask
[1] = 0xffffffffffffffffULL
<< (128 - net
->ipv6
.masksize
);
535 return (((grub_be_to_cpu64 (net
->ipv6
.base
[0]) & mask
[0])
536 == (grub_be_to_cpu64 (addr
->ipv6
[0]) & mask
[0]))
537 && ((grub_be_to_cpu64 (net
->ipv6
.base
[1]) & mask
[1])
538 == (grub_be_to_cpu64 (addr
->ipv6
[1]) & mask
[1])));
545 grub_net_resolve_address (const char *name
,
546 grub_net_network_level_address_t
*addr
)
550 grub_size_t naddresses
;
551 struct grub_net_network_level_address
*addresses
= 0;
553 if (parse_ip (name
, &addr
->ipv4
, &rest
) && *rest
== 0)
555 addr
->type
= GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
;
556 return GRUB_ERR_NONE
;
558 if (parse_ip6 (name
, addr
->ipv6
, &rest
) && *rest
== 0)
560 addr
->type
= GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
;
561 return GRUB_ERR_NONE
;
563 err
= grub_net_dns_lookup (name
, 0, 0, &naddresses
, &addresses
, 1);
567 grub_error (GRUB_ERR_NET_BAD_ADDRESS
, N_("unresolvable address %s"),
569 /* FIXME: use other results as well. */
570 *addr
= addresses
[0];
571 grub_free (addresses
);
572 return GRUB_ERR_NONE
;
576 grub_net_resolve_net_address (const char *name
,
577 grub_net_network_level_netaddress_t
*addr
)
580 if (parse_ip (name
, &addr
->ipv4
.base
, &rest
))
582 addr
->type
= GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
;
585 addr
->ipv4
.masksize
= grub_strtoul (rest
+ 1, (char **) &rest
, 0);
586 if (!grub_errno
&& *rest
== 0)
587 return GRUB_ERR_NONE
;
588 grub_errno
= GRUB_ERR_NONE
;
592 addr
->ipv4
.masksize
= 32;
593 return GRUB_ERR_NONE
;
596 if (parse_ip6 (name
, addr
->ipv6
.base
, &rest
))
598 addr
->type
= GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
;
601 addr
->ipv6
.masksize
= grub_strtoul (rest
+ 1, (char **) &rest
, 0);
602 if (!grub_errno
&& *rest
== 0)
603 return GRUB_ERR_NONE
;
604 grub_errno
= GRUB_ERR_NONE
;
608 addr
->ipv6
.masksize
= 128;
609 return GRUB_ERR_NONE
;
612 return grub_error (GRUB_ERR_NET_BAD_ADDRESS
,
613 N_("unrecognised network address `%s'"),
618 route_cmp (const struct grub_net_route
*a
, const struct grub_net_route
*b
)
620 if (a
== NULL
&& b
== NULL
)
626 if (a
->target
.type
< b
->target
.type
)
628 if (a
->target
.type
> b
->target
.type
)
630 switch (a
->target
.type
)
632 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV
:
634 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
:
635 if (a
->target
.ipv6
.masksize
> b
->target
.ipv6
.masksize
)
637 if (a
->target
.ipv6
.masksize
< b
->target
.ipv6
.masksize
)
640 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
:
641 if (a
->target
.ipv4
.masksize
> b
->target
.ipv4
.masksize
)
643 if (a
->target
.ipv4
.masksize
< b
->target
.ipv4
.masksize
)
651 grub_net_route_address (grub_net_network_level_address_t addr
,
652 grub_net_network_level_address_t
*gateway
,
653 struct grub_net_network_level_interface
**interf
)
655 struct grub_net_route
*route
;
656 unsigned int depth
= 0;
657 unsigned int routecnt
= 0;
658 struct grub_net_network_level_protocol
*prot
= NULL
;
659 grub_net_network_level_address_t curtarget
= addr
;
663 FOR_NET_ROUTES(route
)
666 for (depth
= 0; depth
< routecnt
+ 2 && depth
< GRUB_UINT_MAX
; depth
++)
668 struct grub_net_route
*bestroute
= NULL
;
669 FOR_NET_ROUTES(route
)
671 if (depth
&& prot
!= route
->prot
)
673 if (!match_net (&route
->target
, &curtarget
))
675 if (route_cmp (route
, bestroute
) > 0)
678 if (bestroute
== NULL
)
679 return grub_error (GRUB_ERR_NET_NO_ROUTE
,
680 N_("destination unreachable"));
682 if (!bestroute
->is_gateway
)
684 *interf
= bestroute
->interface
;
685 return GRUB_ERR_NONE
;
688 *gateway
= bestroute
->gw
;
689 curtarget
= bestroute
->gw
;
692 return grub_error (GRUB_ERR_NET_ROUTE_LOOP
,
693 /* TRANSLATORS: route loop is a condition when e.g.
694 to contact server A you need to go through B
695 and to contact B you need to go through A. */
696 N_("route loop detected"));
700 grub_cmd_deladdr (struct grub_command
*cmd
__attribute__ ((unused
)),
701 int argc
, char **args
)
703 struct grub_net_network_level_interface
*inter
;
706 return grub_error (GRUB_ERR_BAD_ARGUMENT
, N_("one argument expected"));
708 FOR_NET_NETWORK_LEVEL_INTERFACES (inter
)
709 if (grub_strcmp (inter
->name
, args
[0]) == 0)
712 return grub_error (GRUB_ERR_BAD_ARGUMENT
, N_("address not found"));
714 if (inter
->flags
& GRUB_NET_INTERFACE_PERMANENT
)
715 return grub_error (GRUB_ERR_IO
,
716 N_("you can't delete this address"));
718 grub_net_network_level_interface_unregister (inter
);
719 grub_free (inter
->name
);
722 return GRUB_ERR_NONE
;
726 grub_net_addr_to_str (const grub_net_network_level_address_t
*target
, char *buf
)
728 switch (target
->type
)
730 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV
:
731 COMPILE_TIME_ASSERT (sizeof ("temporary") < GRUB_NET_MAX_STR_ADDR_LEN
);
732 grub_strcpy (buf
, "temporary");
734 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
:
737 grub_uint64_t n
= grub_be_to_cpu64 (target
->ipv6
[0]);
739 for (i
= 0; i
< 4; i
++)
741 grub_snprintf (ptr
, 6, "%" PRIxGRUB_UINT64_T
":",
742 (n
>> (48 - 16 * i
)) & 0xffff);
743 ptr
+= grub_strlen (ptr
);
745 n
= grub_be_to_cpu64 (target
->ipv6
[1]);
746 for (i
= 0; i
< 3; i
++)
748 grub_snprintf (ptr
, 6, "%" PRIxGRUB_UINT64_T
":",
749 (n
>> (48 - 16 * i
)) & 0xffff);
750 ptr
+= grub_strlen (ptr
);
752 grub_snprintf (ptr
, 5, "%" PRIxGRUB_UINT64_T
, n
& 0xffff);
755 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
:
757 grub_uint32_t n
= grub_be_to_cpu32 (target
->ipv4
);
758 grub_snprintf (buf
, GRUB_NET_MAX_STR_ADDR_LEN
, "%d.%d.%d.%d",
759 ((n
>> 24) & 0xff), ((n
>> 16) & 0xff),
760 ((n
>> 8) & 0xff), ((n
>> 0) & 0xff));
764 grub_snprintf (buf
, GRUB_NET_MAX_STR_ADDR_LEN
,
765 "Unknown address type %d", target
->type
);
770 grub_net_hwaddr_to_str (const grub_net_link_level_address_t
*addr
, char *str
)
775 case GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET
:
779 for (ptr
= str
, i
= 0; i
< ARRAY_SIZE (addr
->mac
); i
++)
781 grub_snprintf (ptr
, GRUB_NET_MAX_STR_HWADDR_LEN
- (ptr
- str
),
782 "%02x:", addr
->mac
[i
] & 0xff);
783 ptr
+= (sizeof ("XX:") - 1);
788 grub_printf (_("Unsupported hw address type %d\n"), addr
->type
);
792 grub_net_hwaddr_cmp (const grub_net_link_level_address_t
*a
,
793 const grub_net_link_level_address_t
*b
)
795 if (a
->type
< b
->type
)
797 if (a
->type
> b
->type
)
801 case GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET
:
802 return grub_memcmp (a
->mac
, b
->mac
, sizeof (a
->mac
));
804 grub_printf (_("Unsupported hw address type %d\n"), a
->type
);
809 grub_net_addr_cmp (const grub_net_network_level_address_t
*a
,
810 const grub_net_network_level_address_t
*b
)
812 if (a
->type
< b
->type
)
814 if (a
->type
> b
->type
)
818 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
:
819 return grub_memcmp (&a
->ipv4
, &b
->ipv4
, sizeof (a
->ipv4
));
820 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
:
821 return grub_memcmp (&a
->ipv6
, &b
->ipv6
, sizeof (a
->ipv6
));
822 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV
:
825 grub_printf (_("Unsupported address type %d\n"), a
->type
);
829 /* FIXME: implement this. */
831 hwaddr_set_env (struct grub_env_var
*var
__attribute__ ((unused
)),
832 const char *val
__attribute__ ((unused
)))
837 /* FIXME: implement this. */
839 addr_set_env (struct grub_env_var
*var
__attribute__ ((unused
)),
840 const char *val
__attribute__ ((unused
)))
846 defserver_set_env (struct grub_env_var
*var
__attribute__ ((unused
)),
849 grub_free (grub_net_default_server
);
850 grub_net_default_server
= grub_strdup (val
);
851 return grub_strdup (val
);
855 defserver_get_env (struct grub_env_var
*var
__attribute__ ((unused
)),
856 const char *val
__attribute__ ((unused
)))
858 return grub_net_default_server
? : "";
862 defip_get_env (struct grub_env_var
*var
__attribute__ ((unused
)),
863 const char *val
__attribute__ ((unused
)))
865 const char *intf
= grub_env_get ("net_default_interface");
866 const char *ret
= NULL
;
869 char *buf
= grub_xasprintf ("net_%s_ip", intf
);
871 ret
= grub_env_get (buf
);
878 defip_set_env (struct grub_env_var
*var
__attribute__ ((unused
)),
881 const char *intf
= grub_env_get ("net_default_interface");
884 char *buf
= grub_xasprintf ("net_%s_ip", intf
);
886 grub_env_set (buf
, val
);
894 defmac_get_env (struct grub_env_var
*var
__attribute__ ((unused
)),
895 const char *val
__attribute__ ((unused
)))
897 const char *intf
= grub_env_get ("net_default_interface");
898 const char *ret
= NULL
;
901 char *buf
= grub_xasprintf ("net_%s_mac", intf
);
903 ret
= grub_env_get (buf
);
910 defmac_set_env (struct grub_env_var
*var
__attribute__ ((unused
)),
913 const char *intf
= grub_env_get ("net_default_interface");
916 char *buf
= grub_xasprintf ("net_%s_mac", intf
);
918 grub_env_set (buf
, val
);
926 grub_net_network_level_interface_register (struct grub_net_network_level_interface
*inter
)
929 char buf
[GRUB_NET_MAX_STR_HWADDR_LEN
];
932 grub_net_hwaddr_to_str (&inter
->hwaddress
, buf
);
933 name
= grub_xasprintf ("net_%s_mac", inter
->name
);
936 for (ptr
= name
; *ptr
; ptr
++)
939 grub_env_set (name
, buf
);
940 grub_register_variable_hook (name
, 0, hwaddr_set_env
);
941 grub_env_export (name
);
946 char buf
[GRUB_NET_MAX_STR_ADDR_LEN
];
949 grub_net_addr_to_str (&inter
->address
, buf
);
950 name
= grub_xasprintf ("net_%s_ip", inter
->name
);
953 for (ptr
= name
; *ptr
; ptr
++)
956 grub_env_set (name
, buf
);
957 grub_register_variable_hook (name
, 0, addr_set_env
);
958 grub_env_export (name
);
962 inter
->card
->num_ifaces
++;
963 inter
->prev
= &grub_net_network_level_interfaces
;
964 inter
->next
= grub_net_network_level_interfaces
;
966 inter
->next
->prev
= &inter
->next
;
967 grub_net_network_level_interfaces
= inter
;
972 grub_net_add_ipv4_local (struct grub_net_network_level_interface
*inter
,
975 grub_uint32_t ip_cpu
;
976 struct grub_net_route
*route
;
978 if (inter
->address
.type
!= GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
)
981 ip_cpu
= grub_be_to_cpu32 (inter
->address
.ipv4
);
985 if (!(ip_cpu
& 0x80000000))
987 else if (!(ip_cpu
& 0x40000000))
989 else if (!(ip_cpu
& 0x20000000))
995 route
= grub_zalloc (sizeof (*route
));
999 route
->name
= grub_xasprintf ("%s:local", inter
->name
);
1006 route
->target
.type
= GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
;
1007 route
->target
.ipv4
.base
= grub_cpu_to_be32 (ip_cpu
& (0xffffffff << (32 - mask
)));
1008 route
->target
.ipv4
.masksize
= mask
;
1009 route
->is_gateway
= 0;
1010 route
->interface
= inter
;
1012 grub_net_route_register (route
);
1017 /* FIXME: support MAC specifying. */
1019 grub_cmd_addaddr (struct grub_command
*cmd
__attribute__ ((unused
)),
1020 int argc
, char **args
)
1022 struct grub_net_card
*card
;
1023 grub_net_network_level_address_t addr
;
1025 grub_net_interface_flags_t flags
= 0;
1026 struct grub_net_network_level_interface
*inf
;
1029 return grub_error (GRUB_ERR_BAD_ARGUMENT
, N_("three arguments expected"));
1031 FOR_NET_CARDS (card
)
1032 if (grub_strcmp (card
->name
, args
[1]) == 0)
1035 return grub_error (GRUB_ERR_BAD_ARGUMENT
, N_("card not found"));
1037 err
= grub_net_resolve_address (args
[2], &addr
);
1041 if (card
->flags
& GRUB_NET_CARD_NO_MANUAL_INTERFACES
)
1042 return grub_error (GRUB_ERR_IO
,
1043 "this card doesn't support address addition");
1045 if (card
->flags
& GRUB_NET_CARD_HWADDRESS_IMMUTABLE
)
1046 flags
|= GRUB_NET_INTERFACE_HWADDRESS_IMMUTABLE
;
1048 inf
= grub_net_add_addr (args
[0], card
, &addr
, &card
->default_address
,
1051 grub_net_add_ipv4_local (inf
, -1);
1057 grub_cmd_delroute (struct grub_command
*cmd
__attribute__ ((unused
)),
1058 int argc
, char **args
)
1060 struct grub_net_route
*route
;
1061 struct grub_net_route
**prev
;
1064 return grub_error (GRUB_ERR_BAD_ARGUMENT
, N_("one argument expected"));
1066 for (prev
= &grub_net_routes
, route
= *prev
; route
; prev
= &((*prev
)->next
),
1068 if (grub_strcmp (route
->name
, args
[0]) == 0)
1070 *prev
= route
->next
;
1071 grub_free (route
->name
);
1077 return GRUB_ERR_NONE
;
1081 grub_net_add_route (const char *name
,
1082 grub_net_network_level_netaddress_t target
,
1083 struct grub_net_network_level_interface
*inter
)
1085 struct grub_net_route
*route
;
1087 route
= grub_zalloc (sizeof (*route
));
1091 route
->name
= grub_strdup (name
);
1098 route
->target
= target
;
1099 route
->is_gateway
= 0;
1100 route
->interface
= inter
;
1102 grub_net_route_register (route
);
1104 return GRUB_ERR_NONE
;
1108 grub_net_add_route_gw (const char *name
,
1109 grub_net_network_level_netaddress_t target
,
1110 grub_net_network_level_address_t gw
)
1112 struct grub_net_route
*route
;
1114 route
= grub_zalloc (sizeof (*route
));
1118 route
->name
= grub_strdup (name
);
1125 route
->target
= target
;
1126 route
->is_gateway
= 1;
1129 grub_net_route_register (route
);
1131 return GRUB_ERR_NONE
;
1135 grub_cmd_addroute (struct grub_command
*cmd
__attribute__ ((unused
)),
1136 int argc
, char **args
)
1138 grub_net_network_level_netaddress_t target
;
1140 return grub_error (GRUB_ERR_BAD_ARGUMENT
,
1141 N_("three arguments expected"));
1143 grub_net_resolve_net_address (args
[1], &target
);
1145 if (grub_strcmp (args
[2], "gw") == 0 && argc
>= 4)
1148 grub_net_network_level_address_t gw
;
1150 err
= grub_net_resolve_address (args
[3], &gw
);
1153 return grub_net_add_route_gw (args
[0], target
, gw
);
1157 struct grub_net_network_level_interface
*inter
;
1159 FOR_NET_NETWORK_LEVEL_INTERFACES (inter
)
1160 if (grub_strcmp (inter
->name
, args
[2]) == 0)
1164 return grub_error (GRUB_ERR_BAD_ARGUMENT
,
1165 N_("unrecognised network interface `%s'"), args
[2]);
1166 return grub_net_add_route (args
[0], target
, inter
);
1171 print_net_address (const grub_net_network_level_netaddress_t
*target
)
1173 switch (target
->type
)
1175 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV
:
1176 /* TRANSLATORS: it refers to the network address. */
1177 grub_printf ("%s\n", _("temporary"));
1179 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
:
1181 grub_uint32_t n
= grub_be_to_cpu32 (target
->ipv4
.base
);
1182 grub_printf ("%d.%d.%d.%d/%d ", ((n
>> 24) & 0xff),
1186 target
->ipv4
.masksize
);
1189 case GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
:
1191 char buf
[GRUB_NET_MAX_STR_ADDR_LEN
];
1192 struct grub_net_network_level_address base
;
1193 base
.type
= GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
;
1194 grub_memcpy (&base
.ipv6
, &target
->ipv6
, 16);
1195 grub_net_addr_to_str (&base
, buf
);
1196 grub_printf ("%s/%d ", buf
, target
->ipv6
.masksize
);
1200 grub_printf (_("Unknown address type %d\n"), target
->type
);
1204 print_address (const grub_net_network_level_address_t
*target
)
1206 char buf
[GRUB_NET_MAX_STR_ADDR_LEN
];
1207 grub_net_addr_to_str (target
, buf
);
1212 grub_cmd_listroutes (struct grub_command
*cmd
__attribute__ ((unused
)),
1213 int argc
__attribute__ ((unused
)),
1214 char **args
__attribute__ ((unused
)))
1216 struct grub_net_route
*route
;
1217 FOR_NET_ROUTES(route
)
1219 grub_printf ("%s ", route
->name
);
1220 print_net_address (&route
->target
);
1221 if (route
->is_gateway
)
1223 grub_printf ("gw ");
1224 print_address (&route
->gw
);
1227 grub_printf ("%s", route
->interface
->name
);
1230 return GRUB_ERR_NONE
;
1234 grub_cmd_listcards (struct grub_command
*cmd
__attribute__ ((unused
)),
1235 int argc
__attribute__ ((unused
)),
1236 char **args
__attribute__ ((unused
)))
1238 struct grub_net_card
*card
;
1241 char buf
[GRUB_NET_MAX_STR_HWADDR_LEN
];
1242 grub_net_hwaddr_to_str (&card
->default_address
, buf
);
1243 grub_printf ("%s %s\n", card
->name
, buf
);
1245 return GRUB_ERR_NONE
;
1249 grub_cmd_listaddrs (struct grub_command
*cmd
__attribute__ ((unused
)),
1250 int argc
__attribute__ ((unused
)),
1251 char **args
__attribute__ ((unused
)))
1253 struct grub_net_network_level_interface
*inf
;
1254 FOR_NET_NETWORK_LEVEL_INTERFACES (inf
)
1256 char bufh
[GRUB_NET_MAX_STR_HWADDR_LEN
];
1257 char bufn
[GRUB_NET_MAX_STR_ADDR_LEN
];
1258 grub_net_hwaddr_to_str (&inf
->hwaddress
, bufh
);
1259 grub_net_addr_to_str (&inf
->address
, bufn
);
1260 grub_printf ("%s %s %s\n", inf
->name
, bufh
, bufn
);
1262 return GRUB_ERR_NONE
;
1265 grub_net_app_level_t grub_net_app_level_list
;
1266 struct grub_net_socket
*grub_net_sockets
;
1269 grub_net_open_real (const char *name
)
1271 grub_net_app_level_t proto
;
1272 const char *protname
, *server
;
1273 grub_size_t protnamelen
;
1276 if (grub_strncmp (name
, "pxe:", sizeof ("pxe:") - 1) == 0)
1279 protnamelen
= sizeof ("tftp") - 1;
1280 server
= name
+ sizeof ("pxe:") - 1;
1282 else if (grub_strcmp (name
, "pxe") == 0)
1285 protnamelen
= sizeof ("tftp") - 1;
1286 server
= grub_net_default_server
;
1291 comma
= grub_strchr (name
, ',');
1294 protnamelen
= comma
- name
;
1300 protnamelen
= grub_strlen (name
);
1301 server
= grub_net_default_server
;
1307 grub_error (GRUB_ERR_NET_BAD_ADDRESS
,
1308 N_("no server is specified"));
1312 for (try = 0; try < 2; try++)
1314 FOR_NET_APP_LEVEL (proto
)
1316 if (grub_memcmp (proto
->name
, protname
, protnamelen
) == 0
1317 && proto
->name
[protnamelen
] == 0)
1319 grub_net_t ret
= grub_zalloc (sizeof (*ret
));
1322 ret
->protocol
= proto
;
1325 ret
->server
= grub_strdup (server
);
1334 ret
->fs
= &grub_net_fs
;
1342 if (sizeof ("http") - 1 == protnamelen
1343 && grub_memcmp ("http", protname
, protnamelen
) == 0)
1345 grub_dl_load ("http");
1346 grub_errno
= GRUB_ERR_NONE
;
1349 if (sizeof ("tftp") - 1 == protnamelen
1350 && grub_memcmp ("tftp", protname
, protnamelen
) == 0)
1352 grub_dl_load ("tftp");
1353 grub_errno
= GRUB_ERR_NONE
;
1360 /* Restore original error. */
1361 grub_error (GRUB_ERR_UNKNOWN_DEVICE
, N_("disk `%s' not found"),
1368 grub_net_fs_dir (grub_device_t device
, const char *path
__attribute__ ((unused
)),
1369 grub_fs_dir_hook_t hook
__attribute__ ((unused
)),
1370 void *hook_data
__attribute__ ((unused
)))
1373 return grub_error (GRUB_ERR_BUG
, "invalid net device");
1374 return GRUB_ERR_NONE
;
1378 grub_net_fs_open (struct grub_file
*file_out
, const char *name
)
1381 struct grub_file
*file
, *bufio
;
1383 file
= grub_malloc (sizeof (*file
));
1387 grub_memcpy (file
, file_out
, sizeof (struct grub_file
));
1388 file
->device
->net
->packs
.first
= NULL
;
1389 file
->device
->net
->packs
.last
= NULL
;
1390 file
->device
->net
->name
= grub_strdup (name
);
1391 if (!file
->device
->net
->name
)
1394 err
= file
->device
->net
->protocol
->open (file
, name
);
1397 while (file
->device
->net
->packs
.first
)
1399 grub_netbuff_free (file
->device
->net
->packs
.first
->nb
);
1400 grub_net_remove_packet (file
->device
->net
->packs
.first
);
1402 grub_free (file
->device
->net
->name
);
1406 bufio
= grub_bufio_open (file
, 32768);
1409 while (file
->device
->net
->packs
.first
)
1411 grub_netbuff_free (file
->device
->net
->packs
.first
->nb
);
1412 grub_net_remove_packet (file
->device
->net
->packs
.first
);
1414 file
->device
->net
->protocol
->close (file
);
1415 grub_free (file
->device
->net
->name
);
1420 grub_memcpy (file_out
, bufio
, sizeof (struct grub_file
));
1422 return GRUB_ERR_NONE
;
1426 grub_net_fs_close (grub_file_t file
)
1428 while (file
->device
->net
->packs
.first
)
1430 grub_netbuff_free (file
->device
->net
->packs
.first
->nb
);
1431 grub_net_remove_packet (file
->device
->net
->packs
.first
);
1433 file
->device
->net
->protocol
->close (file
);
1434 grub_free (file
->device
->net
->name
);
1435 return GRUB_ERR_NONE
;
1439 receive_packets (struct grub_net_card
*card
, int *stop_condition
)
1442 if (card
->num_ifaces
== 0)
1446 grub_err_t err
= GRUB_ERR_NONE
;
1447 if (card
->driver
->open
)
1448 err
= card
->driver
->open (card
);
1451 grub_errno
= GRUB_ERR_NONE
;
1456 while (received
< 100)
1458 /* Maybe should be better have a fixed number of packets for each card
1459 and just mark them as used and not used. */
1460 struct grub_net_buff
*nb
;
1462 if (received
> 10 && stop_condition
&& *stop_condition
)
1465 nb
= card
->driver
->recv (card
);
1468 card
->last_poll
= grub_get_time_ms ();
1472 grub_net_recv_ethernet_packet (nb
, card
);
1475 grub_dprintf ("net", "error receiving: %d: %s\n", grub_errno
,
1477 grub_errno
= GRUB_ERR_NONE
;
1480 grub_print_error ();
1484 grub_net_poll_cards (unsigned time
, int *stop_condition
)
1486 struct grub_net_card
*card
;
1487 grub_uint64_t start_time
;
1488 start_time
= grub_get_time_ms ();
1489 while ((grub_get_time_ms () - start_time
) < time
1490 && (!stop_condition
|| !*stop_condition
))
1491 FOR_NET_CARDS (card
)
1492 receive_packets (card
, stop_condition
);
1493 grub_net_tcp_retransmit ();
1497 grub_net_poll_cards_idle_real (void)
1499 struct grub_net_card
*card
;
1500 FOR_NET_CARDS (card
)
1502 grub_uint64_t ctime
= grub_get_time_ms ();
1504 if (ctime
< card
->last_poll
1505 || ctime
>= card
->last_poll
+ card
->idle_poll_delay_ms
)
1506 receive_packets (card
, 0);
1508 grub_net_tcp_retransmit ();
1511 /* Read from the packets list*/
1513 grub_net_fs_read_real (grub_file_t file
, char *buf
, grub_size_t len
)
1515 grub_net_t net
= file
->device
->net
;
1516 struct grub_net_buff
*nb
;
1518 grub_size_t amount
, total
= 0;
1521 while (try <= GRUB_NET_TRIES
)
1523 while (net
->packs
.first
)
1526 nb
= net
->packs
.first
->nb
;
1527 amount
= nb
->tail
- nb
->data
;
1532 file
->device
->net
->offset
+= amount
;
1533 if (grub_file_progress_hook
)
1534 grub_file_progress_hook (0, 0, amount
, file
);
1537 grub_memcpy (ptr
, nb
->data
, amount
);
1540 if (amount
== (grub_size_t
) (nb
->tail
- nb
->data
))
1542 grub_netbuff_free (nb
);
1543 grub_net_remove_packet (net
->packs
.first
);
1550 if (net
->protocol
->packets_pulled
)
1551 net
->protocol
->packets_pulled (file
);
1555 if (net
->protocol
->packets_pulled
)
1556 net
->protocol
->packets_pulled (file
);
1561 grub_net_poll_cards (GRUB_NET_INTERVAL
, &net
->stall
);
1566 grub_error (GRUB_ERR_TIMEOUT
, N_("timeout reading `%s'"), net
->name
);
1571 have_ahead (struct grub_file
*file
)
1573 grub_net_t net
= file
->device
->net
;
1574 grub_off_t ret
= net
->offset
;
1575 struct grub_net_packet
*pack
;
1576 for (pack
= net
->packs
.first
; pack
; pack
= pack
->next
)
1577 ret
+= pack
->nb
->tail
- pack
->nb
->data
;
1582 grub_net_seek_real (struct grub_file
*file
, grub_off_t offset
)
1584 if (offset
== file
->device
->net
->offset
)
1585 return GRUB_ERR_NONE
;
1587 if (offset
> file
->device
->net
->offset
)
1589 if (!file
->device
->net
->protocol
->seek
|| have_ahead (file
) >= offset
)
1591 grub_net_fs_read_real (file
, NULL
,
1592 offset
- file
->device
->net
->offset
);
1595 return file
->device
->net
->protocol
->seek (file
, offset
);
1600 if (file
->device
->net
->protocol
->seek
)
1601 return file
->device
->net
->protocol
->seek (file
, offset
);
1602 while (file
->device
->net
->packs
.first
)
1604 grub_netbuff_free (file
->device
->net
->packs
.first
->nb
);
1605 grub_net_remove_packet (file
->device
->net
->packs
.first
);
1607 file
->device
->net
->protocol
->close (file
);
1609 file
->device
->net
->packs
.first
= NULL
;
1610 file
->device
->net
->packs
.last
= NULL
;
1611 file
->device
->net
->offset
= 0;
1612 file
->device
->net
->eof
= 0;
1613 err
= file
->device
->net
->protocol
->open (file
, file
->device
->net
->name
);
1616 grub_net_fs_read_real (file
, NULL
, offset
);
1622 grub_net_fs_read (grub_file_t file
, char *buf
, grub_size_t len
)
1624 if (file
->offset
!= file
->device
->net
->offset
)
1627 err
= grub_net_seek_real (file
, file
->offset
);
1631 return grub_net_fs_read_real (file
, buf
, len
);
1634 static struct grub_fs grub_net_fs
=
1637 .dir
= grub_net_fs_dir
,
1638 .open
= grub_net_fs_open
,
1639 .read
= grub_net_fs_read
,
1640 .close
= grub_net_fs_close
,
1647 grub_net_fini_hw (int noreturn
__attribute__ ((unused
)))
1649 struct grub_net_card
*card
;
1650 FOR_NET_CARDS (card
)
1653 if (card
->driver
->close
)
1654 card
->driver
->close (card
);
1657 return GRUB_ERR_NONE
;
1661 grub_net_restore_hw (void)
1663 return GRUB_ERR_NONE
;
1666 static struct grub_preboot
*fini_hnd
;
1668 static grub_command_t cmd_addaddr
, cmd_deladdr
, cmd_addroute
, cmd_delroute
;
1669 static grub_command_t cmd_lsroutes
, cmd_lscards
;
1670 static grub_command_t cmd_lsaddr
, cmd_slaac
;
1674 grub_register_variable_hook ("net_default_server", defserver_get_env
,
1676 grub_env_export ("net_default_server");
1677 grub_register_variable_hook ("pxe_default_server", defserver_get_env
,
1679 grub_env_export ("pxe_default_server");
1680 grub_register_variable_hook ("net_default_ip", defip_get_env
,
1682 grub_env_export ("net_default_ip");
1683 grub_register_variable_hook ("net_default_mac", defmac_get_env
,
1685 grub_env_export ("net_default_mac");
1687 cmd_addaddr
= grub_register_command ("net_add_addr", grub_cmd_addaddr
,
1688 /* TRANSLATORS: HWADDRESS stands for
1689 "hardware address". */
1690 N_("SHORTNAME CARD ADDRESS [HWADDRESS]"),
1691 N_("Add a network address."));
1692 cmd_slaac
= grub_register_command ("net_ipv6_autoconf",
1693 grub_cmd_ipv6_autoconf
,
1694 N_("[CARD [HWADDRESS]]"),
1695 N_("Perform an IPV6 autoconfiguration"));
1697 cmd_deladdr
= grub_register_command ("net_del_addr", grub_cmd_deladdr
,
1699 N_("Delete a network address."));
1700 cmd_addroute
= grub_register_command ("net_add_route", grub_cmd_addroute
,
1701 /* TRANSLATORS: "gw" is a keyword. */
1702 N_("SHORTNAME NET [INTERFACE| gw GATEWAY]"),
1703 N_("Add a network route."));
1704 cmd_delroute
= grub_register_command ("net_del_route", grub_cmd_delroute
,
1706 N_("Delete a network route."));
1707 cmd_lsroutes
= grub_register_command ("net_ls_routes", grub_cmd_listroutes
,
1708 "", N_("list network routes"));
1709 cmd_lscards
= grub_register_command ("net_ls_cards", grub_cmd_listcards
,
1710 "", N_("list network cards"));
1711 cmd_lsaddr
= grub_register_command ("net_ls_addr", grub_cmd_listaddrs
,
1712 "", N_("list network addresses"));
1716 grub_net_open
= grub_net_open_real
;
1717 fini_hnd
= grub_loader_register_preboot_hook (grub_net_fini_hw
,
1718 grub_net_restore_hw
,
1719 GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK
);
1720 grub_net_poll_cards_idle
= grub_net_poll_cards_idle_real
;
1725 grub_register_variable_hook ("net_default_server", 0, 0);
1726 grub_register_variable_hook ("pxe_default_server", 0, 0);
1730 grub_unregister_command (cmd_addaddr
);
1731 grub_unregister_command (cmd_deladdr
);
1732 grub_unregister_command (cmd_addroute
);
1733 grub_unregister_command (cmd_delroute
);
1734 grub_unregister_command (cmd_lsroutes
);
1735 grub_unregister_command (cmd_lscards
);
1736 grub_unregister_command (cmd_lsaddr
);
1737 grub_unregister_command (cmd_slaac
);
1738 grub_fs_unregister (&grub_net_fs
);
1739 grub_net_open
= NULL
;
1740 grub_net_fini_hw (0);
1741 grub_loader_unregister_preboot_hook (fini_hnd
);
1742 grub_net_poll_cards_idle
= grub_net_poll_cards_idle_real
;