net.h 14.5 KB
Newer Older
okuji's avatar
okuji committed
1
/*
2
 *  GRUB  --  GRand Unified Bootloader
3
 *  Copyright (C) 2010,2011  Free Software Foundation, Inc.
okuji's avatar
okuji committed
4
 *
5
 *  GRUB is free software: you can redistribute it and/or modify
okuji's avatar
okuji committed
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
okuji's avatar
okuji committed
8 9
 *  (at your option) any later version.
 *
10
 *  GRUB is distributed in the hope that it will be useful,
okuji's avatar
okuji committed
11 12 13 14 15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
16
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
okuji's avatar
okuji committed
17 18
 */

19 20
#ifndef GRUB_NET_HEADER
#define GRUB_NET_HEADER	1
okuji's avatar
okuji committed
21

22
#include <grub/types.h>
23 24
#include <grub/err.h>
#include <grub/list.h>
25
#include <grub/fs.h>
26
#include <grub/file.h>
27
#include <grub/mm.h>
28
#include <grub/net/netbuff.h>
29

30 31 32 33 34 35
enum
  {
    GRUB_NET_MAX_LINK_HEADER_SIZE = 64,
    GRUB_NET_UDP_HEADER_SIZE = 8,
    GRUB_NET_TCP_HEADER_SIZE = 20,
    GRUB_NET_OUR_IPV4_HEADER_SIZE = 20,
36
    GRUB_NET_OUR_IPV6_HEADER_SIZE = 40,
37
    GRUB_NET_OUR_MAX_IP_HEADER_SIZE = 40,
38 39 40 41
    GRUB_NET_TCP_RESERVE_SIZE = GRUB_NET_TCP_HEADER_SIZE 
    + GRUB_NET_OUR_IPV4_HEADER_SIZE
    + GRUB_NET_MAX_LINK_HEADER_SIZE
  };
42

43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
typedef enum grub_link_level_protocol_id 
{
  GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET
} grub_link_level_protocol_id_t;

typedef struct grub_net_link_level_address
{
  grub_link_level_protocol_id_t type;
  union
  {
    grub_uint8_t mac[6];
  };
} grub_net_link_level_address_t;

typedef enum grub_net_interface_flags
  {
    GRUB_NET_INTERFACE_HWADDRESS_IMMUTABLE = 1,
    GRUB_NET_INTERFACE_ADDRESS_IMMUTABLE = 2,
    GRUB_NET_INTERFACE_PERMANENT = 4
  } grub_net_interface_flags_t;

typedef enum grub_net_card_flags
  {
    GRUB_NET_CARD_HWADDRESS_IMMUTABLE = 1,
    GRUB_NET_CARD_NO_MANUAL_INTERFACES = 2
  } grub_net_card_flags_t;

70
struct grub_net_card;
okuji's avatar
okuji committed
71

72
struct grub_net_card_driver
okuji's avatar
okuji committed
73
{
74
  struct grub_net_card_driver *next;
75
  struct grub_net_card_driver **prev;
76
  const char *name;
77 78 79
  grub_err_t (*open) (struct grub_net_card *dev);
  void (*close) (struct grub_net_card *dev);
  grub_err_t (*send) (struct grub_net_card *dev,
80
		      struct grub_net_buff *buf);
81
  struct grub_net_buff * (*recv) (struct grub_net_card *dev);
82
};
okuji's avatar
okuji committed
83

84 85 86 87 88 89 90 91 92 93 94 95
typedef struct grub_net_packet
{
  struct grub_net_packet *next;
  struct grub_net_packet *prev;
  struct grub_net_packets *up;
  struct grub_net_buff *nb;
} grub_net_packet_t;

typedef struct grub_net_packets
{
  grub_net_packet_t *first;
  grub_net_packet_t *last;
96
  grub_size_t count;
97
} grub_net_packets_t;
okuji's avatar
okuji committed
98

99 100 101 102
#ifdef GRUB_MACHINE_EFI
#include <grub/efi/api.h>
#endif

103 104 105
struct grub_net_slaac_mac_list
{
  struct grub_net_slaac_mac_list *next;
106
  struct grub_net_slaac_mac_list **prev;
107 108 109 110 111
  grub_net_link_level_address_t address;
  int slaac_counter;
  char *name;
};

112 113
struct grub_net_link_layer_entry;

114 115 116
struct grub_net_card
{
  struct grub_net_card *next;
117
  struct grub_net_card **prev;
118
  const char *name;
119
  struct grub_net_card_driver *driver;
120 121
  grub_net_link_level_address_t default_address;
  grub_net_card_flags_t flags;
122 123
  int num_ifaces;
  int opened;
124 125
  unsigned idle_poll_delay_ms;
  grub_uint64_t last_poll;
126
  grub_size_t mtu;
127
  struct grub_net_slaac_mac_list *slaac_list;
128 129
  grub_ssize_t new_ll_entry;
  struct grub_net_link_layer_entry *link_layer_table;
130 131 132
  void *txbuf;
  void *rcvbuf;
  grub_size_t rcvbufsize;
133
  grub_size_t txbufsize;
134
  int txbusy;
135 136
  union
  {
137
#ifdef GRUB_MACHINE_EFI
138 139 140
    struct
    {
      struct grub_efi_simple_network *efi_net;
141
      grub_efi_handle_t efi_handle;
142
      grub_size_t last_pkt_size;
143
    };
144
#endif
145 146 147
    void *data;
    int data_num;
  };
okuji's avatar
okuji committed
148 149
};

150
struct grub_net_network_level_interface;
okuji's avatar
okuji committed
151

152 153
typedef enum grub_network_level_protocol_id 
{
154
  GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV,
155 156
  GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4,
  GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6
157 158
} grub_network_level_protocol_id_t;

159 160 161 162 163 164 165 166
typedef enum
{
  DNS_OPTION_IPV4,
  DNS_OPTION_IPV6,
  DNS_OPTION_PREFER_IPV4,
  DNS_OPTION_PREFER_IPV6
} grub_dns_option_t;

167
typedef struct grub_net_network_level_address
okuji's avatar
okuji committed
168
{
169
  grub_network_level_protocol_id_t type;
170 171 172
  union
  {
    grub_uint32_t ipv4;
173
    grub_uint64_t ipv6[2];
174
  };
175
  grub_dns_option_t option;
176
} grub_net_network_level_address_t;
177

178
typedef struct grub_net_network_level_netaddress
179
{
180
  grub_network_level_protocol_id_t type;
181 182 183 184 185 186
  union
  {
    struct {
      grub_uint32_t base;
      int masksize; 
    } ipv4;
187 188 189 190
    struct {
      grub_uint64_t base[2];
      int masksize; 
    } ipv6;
191
  };
192
} grub_net_network_level_netaddress_t;
okuji's avatar
okuji committed
193

Josef Bacik's avatar
Josef Bacik committed
194 195 196 197 198 199 200 201 202 203 204 205
struct grub_net_route
{
  struct grub_net_route *next;
  struct grub_net_route **prev;
  grub_net_network_level_netaddress_t target;
  char *name;
  struct grub_net_network_level_protocol *prot;
  int is_gateway;
  struct grub_net_network_level_interface *interface;
  grub_net_network_level_address_t gw;
};

206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
#define FOR_PACKETS(cont,var) for (var = (cont).first; var; var = var->next)

static inline grub_err_t
grub_net_put_packet (grub_net_packets_t *pkts, struct grub_net_buff *nb)
{
  struct grub_net_packet *n;

  n = grub_malloc (sizeof (*n));
  if (!n)
    return grub_errno;

  n->nb = nb;
  n->next = NULL;
  n->prev = NULL;
  n->up = pkts;
  if (pkts->first)
    {
      pkts->last->next = n;
      pkts->last = n;
      n->prev = pkts->last;
    }
  else
    pkts->first = pkts->last = n;

230 231
  pkts->count++;

232 233 234 235 236 237
  return GRUB_ERR_NONE;
}

static inline void
grub_net_remove_packet (grub_net_packet_t *pkt)
{
238 239
  pkt->up->count--;

240 241 242 243 244 245 246 247
  if (pkt->prev)
    pkt->prev->next = pkt->next;
  else
    pkt->up->first = pkt->next;
  if (pkt->next)
    pkt->next->prev = pkt->prev;
  else
    pkt->up->last = pkt->prev;
248
  grub_free (pkt);
249
}
250

251 252 253 254 255 256 257
typedef struct grub_net_app_protocol *grub_net_app_level_t;

typedef struct grub_net_socket *grub_net_socket_t;

struct grub_net_app_protocol 
{
  struct grub_net_app_protocol *next;
258
  struct grub_net_app_protocol **prev;
259
  const char *name;
260 261 262 263
  grub_err_t (*dir) (grub_device_t device, const char *path,
		     int (*hook) (const char *filename,
				  const struct grub_dirhook_info *info));
  grub_err_t (*open) (struct grub_file *file, const char *filename);
264
  grub_err_t (*seek) (struct grub_file *file, grub_off_t off);
265
  grub_err_t (*close) (struct grub_file *file);
266
  grub_err_t (*packets_pulled) (struct grub_file *file);
267 268 269 270
};

typedef struct grub_net
{
271
  char *server;
272
  char *name;
273
  grub_net_app_level_t protocol;
274
  grub_net_packets_t packs;
275
  grub_off_t offset;
276
  grub_fs_t fs;
277
  int eof;
278
  int stall;
279 280 281 282
} *grub_net_t;

extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name);

283 284 285
struct grub_net_network_level_interface
{
  struct grub_net_network_level_interface *next;
286
  struct grub_net_network_level_interface **prev;
287
  char *name;
288
  struct grub_net_card *card;
289
  grub_net_network_level_address_t address;
290 291
  grub_net_link_level_address_t hwaddress;
  grub_net_interface_flags_t flags;
292
  struct grub_net_bootp_packet *dhcp_ack;
293
  grub_size_t dhcp_acklen;
okuji's avatar
okuji committed
294 295 296
  void *data;
};

297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
struct grub_net_session;

struct grub_net_session_level_protocol
{
  void (*close) (struct grub_net_session *session);
  grub_ssize_t (*recv) (struct grub_net_session *session, void *buf,
		       grub_size_t size);
  grub_err_t (*send) (struct grub_net_session *session, void *buf,
		      grub_size_t size);
};

struct grub_net_session
{
  struct grub_net_session_level_protocol *protocol;
  void *data;
};

static inline void
grub_net_session_close (struct grub_net_session *session)
{
  session->protocol->close (session);
}

static inline grub_err_t
grub_net_session_send (struct grub_net_session *session, void *buf,
		       grub_size_t size)
{
  return session->protocol->send (session, buf, size);
}

static inline grub_ssize_t
grub_net_session_recv (struct grub_net_session *session, void *buf,
		       grub_size_t size)
{
  return session->protocol->recv (session, buf, size);
}

334
struct grub_net_network_level_interface *
335
grub_net_add_addr (const char *name,
336
		   struct grub_net_card *card,
337 338
		   const grub_net_network_level_address_t *addr,
		   const grub_net_link_level_address_t *hwaddress,
339
		   grub_net_interface_flags_t flags);
340

341
extern struct grub_net_network_level_interface *grub_net_network_level_interfaces;
342
#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next)
343 344
#define FOR_NET_NETWORK_LEVEL_INTERFACES_SAFE(var,next) for (var = grub_net_network_level_interfaces, next = (var ? var->next : 0); var; var = next, next = (var ? var->next : 0))

345

346 347 348 349 350 351 352 353 354 355 356 357 358 359
extern grub_net_app_level_t grub_net_app_level_list;

#ifndef GRUB_LST_GENERATOR
static inline void
grub_net_app_level_register (grub_net_app_level_t proto)
{
  grub_list_push (GRUB_AS_LIST_P (&grub_net_app_level_list),
		  GRUB_AS_LIST (proto));
}
#endif

static inline void
grub_net_app_level_unregister (grub_net_app_level_t proto)
{
360
  grub_list_remove (GRUB_AS_LIST (proto));
361 362 363 364 365
}

#define FOR_NET_APP_LEVEL(var) FOR_LIST_ELEMENTS((var), \
						 (grub_net_app_level_list))

366 367 368 369 370 371 372 373 374
extern struct grub_net_card *grub_net_cards;

static inline void
grub_net_card_register (struct grub_net_card *card)
{
  grub_list_push (GRUB_AS_LIST_P (&grub_net_cards),
		  GRUB_AS_LIST (card));
}

375 376
void
grub_net_card_unregister (struct grub_net_card *card);
377 378

#define FOR_NET_CARDS(var) for (var = grub_net_cards; var; var = var->next)
379
#define FOR_NET_CARDS_SAFE(var, next) for (var = grub_net_cards, next = (var ? var->next : 0); var; var = next, next = (var ? var->next : 0))
380

381

Josef Bacik's avatar
Josef Bacik committed
382 383 384 385 386 387 388 389 390 391
extern struct grub_net_route *grub_net_routes;

static inline void
grub_net_route_register (struct grub_net_route *route)
{
  grub_list_push (GRUB_AS_LIST_P (&grub_net_routes),
		  GRUB_AS_LIST (route));
}

#define FOR_NET_ROUTES(var) for (var = grub_net_routes; var; var = var->next)
392 393 394 395
struct grub_net_session *
grub_net_open_tcp (char *address, grub_uint16_t port);

grub_err_t
396
grub_net_resolve_address (const char *name,
397 398
			  grub_net_network_level_address_t *addr);

399 400 401 402
grub_err_t
grub_net_resolve_net_address (const char *name,
			      grub_net_network_level_netaddress_t *addr);

403 404 405 406
grub_err_t
grub_net_route_address (grub_net_network_level_address_t addr,
			grub_net_network_level_address_t *gateway,
			struct grub_net_network_level_interface **interf);
okuji's avatar
okuji committed
407 408


409 410 411 412 413 414 415 416
grub_err_t
grub_net_add_route (const char *name,
		    grub_net_network_level_netaddress_t target,
		    struct grub_net_network_level_interface *inter);

grub_err_t
grub_net_add_route_gw (const char *name,
		       grub_net_network_level_netaddress_t target,
Josef Bacik's avatar
Josef Bacik committed
417 418
		       grub_net_network_level_address_t gw,
		       struct grub_net_network_level_interface *inter);
419 420


421 422 423 424
#define GRUB_NET_BOOTP_MAC_ADDR_LEN	16

typedef grub_uint8_t grub_net_bootp_mac_addr_t[GRUB_NET_BOOTP_MAC_ADDR_LEN];

425
struct grub_net_bootp_packet
426 427 428 429 430 431 432 433 434 435 436 437 438
{
  grub_uint8_t opcode;
  grub_uint8_t hw_type;		/* hardware type.  */
  grub_uint8_t hw_len;		/* hardware addr len.  */
  grub_uint8_t gate_hops;	/* zero it.  */
  grub_uint32_t ident;		/* random number chosen by client.  */
  grub_uint16_t seconds;	/* seconds since did initial bootstrap.  */
  grub_uint16_t flags;
  grub_uint32_t	client_ip;
  grub_uint32_t your_ip;
  grub_uint32_t	server_ip;
  grub_uint32_t	gateway_ip;
  grub_net_bootp_mac_addr_t mac_addr;
439 440
  char server_name[64];
  char boot_file[128];
441
  grub_uint8_t vendor[0];
442
} GRUB_PACKED;
443

444 445 446 447
#define	GRUB_NET_BOOTP_RFC1048_MAGIC_0	0x63
#define	GRUB_NET_BOOTP_RFC1048_MAGIC_1	0x82
#define	GRUB_NET_BOOTP_RFC1048_MAGIC_2	0x53
#define	GRUB_NET_BOOTP_RFC1048_MAGIC_3	0x63
448

449 450 451
enum
  {
    GRUB_NET_BOOTP_PAD = 0x00,
452
    GRUB_NET_BOOTP_NETMASK = 0x01,
453 454 455 456 457 458 459 460 461
    GRUB_NET_BOOTP_ROUTER = 0x03,
    GRUB_NET_BOOTP_DNS = 0x06,
    GRUB_NET_BOOTP_HOSTNAME = 0x0c,
    GRUB_NET_BOOTP_DOMAIN = 0x0f,
    GRUB_NET_BOOTP_ROOT_PATH = 0x11,
    GRUB_NET_BOOTP_EXTENSIONS_PATH = 0x12,
    GRUB_NET_BOOTP_END = 0xff
  };

462
struct grub_net_network_level_interface *
463
grub_net_configure_by_dhcp_ack (const char *name,
464
				struct grub_net_card *card,
465
				grub_net_interface_flags_t flags,
466
				const struct grub_net_bootp_packet *bp,
467 468
				grub_size_t size,
				int is_def, char **device, char **path);
469

470 471 472 473
grub_err_t
grub_net_add_ipv4_local (struct grub_net_network_level_interface *inf,
			 int mask);

474 475
void
grub_net_process_dhcp (struct grub_net_buff *nb,
476
		       struct grub_net_card *card);
477 478 479 480

int
grub_net_hwaddr_cmp (const grub_net_link_level_address_t *a,
		     const grub_net_link_level_address_t *b);
481 482 483
int
grub_net_addr_cmp (const grub_net_network_level_address_t *a,
		   const grub_net_network_level_address_t *b);
484 485


486
/*
487
  Currently supported adresses:
488
  IPv4:   XXX.XXX.XXX.XXX
489
  IPv6:   XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX
490
 */
491
#define GRUB_NET_MAX_STR_ADDR_LEN sizeof ("XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX")
492

493 494 495 496 497 498 499
/*
  Currently suppoerted adresses:
  ethernet:   XX:XX:XX:XX:XX:XX
 */

#define GRUB_NET_MAX_STR_HWADDR_LEN (sizeof ("XX:XX:XX:XX:XX:XX"))

500 501 502
void
grub_net_addr_to_str (const grub_net_network_level_address_t *target,
		      char *buf);
503 504
void
grub_net_hwaddr_to_str (const grub_net_link_level_address_t *addr, char *str);
505

506 507 508 509
grub_err_t
grub_env_set_net_property (const char *intername, const char *suffix,
                           const char *value, grub_size_t len);

510
void
511
grub_net_poll_cards (unsigned time, int *stop_condition);
512

513 514 515
void grub_bootp_init (void);
void grub_bootp_fini (void);

516 517 518
void grub_dns_init (void);
void grub_dns_fini (void);

519 520 521 522 523 524 525 526 527 528 529
static inline void
grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter)
{
  inter->card->num_ifaces--;
  *inter->prev = inter->next;
  if (inter->next)
    inter->next->prev = inter->prev;
  inter->next = 0;
  inter->prev = 0;
}

530 531 532
void
grub_net_tcp_retransmit (void);

533 534 535 536 537 538 539 540 541 542 543 544
void
grub_net_link_layer_add_address (struct grub_net_card *card,
				 const grub_net_network_level_address_t *nl,
				 const grub_net_link_level_address_t *ll,
				 int override);
int
grub_net_link_layer_resolve_check (struct grub_net_network_level_interface *inf,
				   const grub_net_network_level_address_t *proto_addr);
grub_err_t
grub_net_link_layer_resolve (struct grub_net_network_level_interface *inf,
			     const grub_net_network_level_address_t *proto_addr,
			     grub_net_link_level_address_t *hw_addr);
545 546 547 548 549 550 551
grub_err_t
grub_net_dns_lookup (const char *name,
		     const struct grub_net_network_level_address *servers,
		     grub_size_t n_servers,
		     grub_size_t *naddresses,
		     struct grub_net_network_level_address **addresses,
		     int cache);
552 553 554 555 556
grub_err_t
grub_net_add_dns_server (const struct grub_net_network_level_address *s);
void
grub_net_remove_dns_server (const struct grub_net_network_level_address *s);

557

558 559
extern char *grub_net_default_server;

560 561
#define GRUB_NET_TRIES 40
#define GRUB_NET_INTERVAL 400
562
#define GRUB_NET_INTERVAL_ADDITION 20
563

564
#endif /* ! GRUB_NET_HEADER */