/* * VAS_EBOOT -- GRand Unified Bootloader * Copyright (C) 2010,2011 Free Software Foundation, Inc. * * VAS_EBOOT is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * VAS_EBOOT is distributed in the hope that it will be useful, * 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 * along with VAS_EBOOT. If not, see . */ #ifndef VAS_EBOOT_NET_HEADER #define VAS_EBOOT_NET_HEADER 1 #include #include #include #include #include #include #include enum { VAS_EBOOT_NET_MAX_LINK_HEADER_SIZE = 64, VAS_EBOOT_NET_UDP_HEADER_SIZE = 8, VAS_EBOOT_NET_TCP_HEADER_SIZE = 20, VAS_EBOOT_NET_OUR_IPV4_HEADER_SIZE = 20, VAS_EBOOT_NET_OUR_IPV6_HEADER_SIZE = 40, VAS_EBOOT_NET_OUR_MAX_IP_HEADER_SIZE = 40, VAS_EBOOT_NET_TCP_RESERVE_SIZE = VAS_EBOOT_NET_TCP_HEADER_SIZE + VAS_EBOOT_NET_OUR_IPV4_HEADER_SIZE + VAS_EBOOT_NET_MAX_LINK_HEADER_SIZE }; typedef enum VasEBoot_link_level_protocol_id { VAS_EBOOT_NET_LINK_LEVEL_PROTOCOL_ETHERNET } VasEBoot_link_level_protocol_id_t; typedef struct VasEBoot_net_link_level_address { VasEBoot_link_level_protocol_id_t type; union { VasEBoot_uint8_t mac[6]; }; } VasEBoot_net_link_level_address_t; typedef enum VasEBoot_net_interface_flags { VAS_EBOOT_NET_INTERFACE_HWADDRESS_IMMUTABLE = 1, VAS_EBOOT_NET_INTERFACE_ADDRESS_IMMUTABLE = 2, VAS_EBOOT_NET_INTERFACE_PERMANENT = 4 } VasEBoot_net_interface_flags_t; typedef enum VasEBoot_net_card_flags { VAS_EBOOT_NET_CARD_HWADDRESS_IMMUTABLE = 1, VAS_EBOOT_NET_CARD_NO_MANUAL_INTERFACES = 2, VAS_EBOOT_NET_CARD_NO_CLOSE_ON_FINI_HW = 4 } VasEBoot_net_card_flags_t; struct VasEBoot_net_card; struct VasEBoot_net_card_driver { struct VasEBoot_net_card_driver *next; struct VasEBoot_net_card_driver **prev; const char *name; VasEBoot_err_t (*open) (struct VasEBoot_net_card *dev); void (*close) (struct VasEBoot_net_card *dev); VasEBoot_err_t (*send) (struct VasEBoot_net_card *dev, struct VasEBoot_net_buff *buf); struct VasEBoot_net_buff * (*recv) (struct VasEBoot_net_card *dev); }; typedef struct VasEBoot_net_packet { struct VasEBoot_net_packet *next; struct VasEBoot_net_packet *prev; struct VasEBoot_net_packets *up; struct VasEBoot_net_buff *nb; } VasEBoot_net_packet_t; typedef struct VasEBoot_net_packets { VasEBoot_net_packet_t *first; VasEBoot_net_packet_t *last; VasEBoot_size_t count; } VasEBoot_net_packets_t; #ifdef VAS_EBOOT_MACHINE_EFI #include #endif struct VasEBoot_net_slaac_mac_list { struct VasEBoot_net_slaac_mac_list *next; struct VasEBoot_net_slaac_mac_list **prev; VasEBoot_net_link_level_address_t address; int slaac_counter; char *name; }; struct VasEBoot_net_link_layer_entry; struct VasEBoot_net_card { struct VasEBoot_net_card *next; struct VasEBoot_net_card **prev; const char *name; struct VasEBoot_net_card_driver *driver; VasEBoot_net_link_level_address_t default_address; VasEBoot_net_card_flags_t flags; int num_ifaces; int opened; unsigned idle_poll_delay_ms; VasEBoot_uint64_t last_poll; VasEBoot_size_t mtu; struct VasEBoot_net_slaac_mac_list *slaac_list; VasEBoot_ssize_t new_ll_entry; struct VasEBoot_net_link_layer_entry *link_layer_table; void *txbuf; void *rcvbuf; VasEBoot_size_t rcvbufsize; VasEBoot_size_t txbufsize; int txbusy; union { #ifdef VAS_EBOOT_MACHINE_EFI struct { struct VasEBoot_efi_simple_network *efi_net; VasEBoot_efi_handle_t efi_handle; VasEBoot_size_t last_pkt_size; }; #endif void *data; int data_num; }; }; struct VasEBoot_net_network_level_interface; typedef enum VasEBoot_network_level_protocol_id { VAS_EBOOT_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV, VAS_EBOOT_NET_NETWORK_LEVEL_PROTOCOL_IPV4, VAS_EBOOT_NET_NETWORK_LEVEL_PROTOCOL_IPV6 } VasEBoot_network_level_protocol_id_t; typedef enum { DNS_OPTION_IPV4, DNS_OPTION_IPV6, DNS_OPTION_PREFER_IPV4, DNS_OPTION_PREFER_IPV6 } VasEBoot_dns_option_t; typedef struct VasEBoot_net_network_level_address { VasEBoot_network_level_protocol_id_t type; union { VasEBoot_uint32_t ipv4; VasEBoot_uint64_t ipv6[2]; }; VasEBoot_dns_option_t option; } VasEBoot_net_network_level_address_t; typedef struct VasEBoot_net_network_level_netaddress { VasEBoot_network_level_protocol_id_t type; union { struct { VasEBoot_uint32_t base; int masksize; } ipv4; struct { VasEBoot_uint64_t base[2]; int masksize; } ipv6; }; } VasEBoot_net_network_level_netaddress_t; struct VasEBoot_net_route { struct VasEBoot_net_route *next; struct VasEBoot_net_route **prev; VasEBoot_net_network_level_netaddress_t target; char *name; struct VasEBoot_net_network_level_protocol *prot; int is_gateway; struct VasEBoot_net_network_level_interface *interface; VasEBoot_net_network_level_address_t gw; }; #define FOR_PACKETS(cont,var) for (var = (cont).first; var; var = var->next) static inline VasEBoot_err_t VasEBoot_net_put_packet (VasEBoot_net_packets_t *pkts, struct VasEBoot_net_buff *nb) { struct VasEBoot_net_packet *n; n = VasEBoot_malloc (sizeof (*n)); if (!n) return VasEBoot_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; pkts->count++; return VAS_EBOOT_ERR_NONE; } static inline void VasEBoot_net_remove_packet (VasEBoot_net_packet_t *pkt) { pkt->up->count--; 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; VasEBoot_free (pkt); } typedef struct VasEBoot_net_app_protocol *VasEBoot_net_app_level_t; typedef struct VasEBoot_net_socket *VasEBoot_net_socket_t; struct VasEBoot_net_app_protocol { struct VasEBoot_net_app_protocol *next; struct VasEBoot_net_app_protocol **prev; const char *name; VasEBoot_err_t (*dir) (VasEBoot_device_t device, const char *path, int (*hook) (const char *filename, const struct VasEBoot_dirhook_info *info)); VasEBoot_err_t (*open) (struct VasEBoot_file *file, const char *filename); VasEBoot_err_t (*seek) (struct VasEBoot_file *file, VasEBoot_off_t off); VasEBoot_err_t (*close) (struct VasEBoot_file *file); VasEBoot_err_t (*packets_pulled) (struct VasEBoot_file *file); }; typedef struct VasEBoot_net { char *server; char *name; VasEBoot_uint16_t port; VasEBoot_net_app_level_t protocol; VasEBoot_net_packets_t packs; VasEBoot_off_t offset; VasEBoot_fs_t fs; int eof; int stall; int broken; } *VasEBoot_net_t; extern VasEBoot_net_t (*EXPORT_VAR (VasEBoot_net_open)) (const char *name); struct VasEBoot_net_network_level_interface { struct VasEBoot_net_network_level_interface *next; struct VasEBoot_net_network_level_interface **prev; char *name; struct VasEBoot_net_card *card; VasEBoot_net_network_level_address_t address; VasEBoot_net_link_level_address_t hwaddress; VasEBoot_net_interface_flags_t flags; struct VasEBoot_net_bootp_packet *dhcp_ack; VasEBoot_size_t dhcp_acklen; VasEBoot_uint16_t vlantag; VasEBoot_uint32_t xid; /* DHCPv4 transaction id */ VasEBoot_uint32_t srv_id; /* DHCPv4 server_identifier */ VasEBoot_uint32_t my_ip; /* DHCPv4 offered IP address */ unsigned dhcp_tmo_left; /* DHCPv4 running retransmission timeout */ unsigned dhcp_tmo; /* DHCPv4 current retransmission timeout */ void *data; }; struct VasEBoot_net_session; struct VasEBoot_net_session_level_protocol { void (*close) (struct VasEBoot_net_session *session); VasEBoot_ssize_t (*recv) (struct VasEBoot_net_session *session, void *buf, VasEBoot_size_t size); VasEBoot_err_t (*send) (struct VasEBoot_net_session *session, void *buf, VasEBoot_size_t size); }; struct VasEBoot_net_session { struct VasEBoot_net_session_level_protocol *protocol; void *data; }; static inline void VasEBoot_net_session_close (struct VasEBoot_net_session *session) { session->protocol->close (session); } static inline VasEBoot_err_t VasEBoot_net_session_send (struct VasEBoot_net_session *session, void *buf, VasEBoot_size_t size) { return session->protocol->send (session, buf, size); } static inline VasEBoot_ssize_t VasEBoot_net_session_recv (struct VasEBoot_net_session *session, void *buf, VasEBoot_size_t size) { return session->protocol->recv (session, buf, size); } struct VasEBoot_net_network_level_interface * VasEBoot_net_add_addr (const char *name, struct VasEBoot_net_card *card, const VasEBoot_net_network_level_address_t *addr, const VasEBoot_net_link_level_address_t *hwaddress, VasEBoot_net_interface_flags_t flags); extern struct VasEBoot_net_network_level_interface *VasEBoot_net_network_level_interfaces; #define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = VasEBoot_net_network_level_interfaces; var; var = var->next) #define FOR_NET_NETWORK_LEVEL_INTERFACES_SAFE(var,next) for (var = VasEBoot_net_network_level_interfaces, next = (var ? var->next : 0); var; var = next, next = (var ? var->next : 0)) extern VasEBoot_net_app_level_t VasEBoot_net_app_level_list; #ifndef VAS_EBOOT_LST_GENERATOR static inline void VasEBoot_net_app_level_register (VasEBoot_net_app_level_t proto) { VasEBoot_list_push (VAS_EBOOT_AS_LIST_P (&VasEBoot_net_app_level_list), VAS_EBOOT_AS_LIST (proto)); } #endif static inline void VasEBoot_net_app_level_unregister (VasEBoot_net_app_level_t proto) { VasEBoot_list_remove (VAS_EBOOT_AS_LIST (proto)); } #define FOR_NET_APP_LEVEL(var) FOR_LIST_ELEMENTS((var), \ (VasEBoot_net_app_level_list)) extern struct VasEBoot_net_card *VasEBoot_net_cards; static inline void VasEBoot_net_card_register (struct VasEBoot_net_card *card) { VasEBoot_list_push (VAS_EBOOT_AS_LIST_P (&VasEBoot_net_cards), VAS_EBOOT_AS_LIST (card)); } void VasEBoot_net_card_unregister (struct VasEBoot_net_card *card); #define FOR_NET_CARDS(var) for (var = VasEBoot_net_cards; var; var = var->next) #define FOR_NET_CARDS_SAFE(var, next) for (var = VasEBoot_net_cards, next = (var ? var->next : 0); var; var = next, next = (var ? var->next : 0)) extern struct VasEBoot_net_route *VasEBoot_net_routes; static inline void VasEBoot_net_route_register (struct VasEBoot_net_route *route) { VasEBoot_list_push (VAS_EBOOT_AS_LIST_P (&VasEBoot_net_routes), VAS_EBOOT_AS_LIST (route)); } #define FOR_NET_ROUTES(var) for (var = VasEBoot_net_routes; var; var = var->next) struct VasEBoot_net_session * VasEBoot_net_open_tcp (char *address, VasEBoot_uint16_t port); VasEBoot_err_t VasEBoot_net_resolve_address (const char *name, VasEBoot_net_network_level_address_t *addr); VasEBoot_err_t VasEBoot_net_resolve_net_address (const char *name, VasEBoot_net_network_level_netaddress_t *addr); VasEBoot_err_t VasEBoot_net_route_address (VasEBoot_net_network_level_address_t addr, VasEBoot_net_network_level_address_t *gateway, struct VasEBoot_net_network_level_interface **interf); VasEBoot_err_t VasEBoot_net_add_route (const char *name, VasEBoot_net_network_level_netaddress_t target, struct VasEBoot_net_network_level_interface *inter); VasEBoot_err_t VasEBoot_net_add_route_gw (const char *name, VasEBoot_net_network_level_netaddress_t target, VasEBoot_net_network_level_address_t gw, struct VasEBoot_net_network_level_interface *inter); #define VAS_EBOOT_NET_BOOTP_MAC_ADDR_LEN 16 typedef VasEBoot_uint8_t VasEBoot_net_bootp_mac_addr_t[VAS_EBOOT_NET_BOOTP_MAC_ADDR_LEN]; struct VasEBoot_net_bootp_packet { VasEBoot_uint8_t opcode; VasEBoot_uint8_t hw_type; /* hardware type. */ VasEBoot_uint8_t hw_len; /* hardware addr len. */ VasEBoot_uint8_t gate_hops; /* zero it. */ VasEBoot_uint32_t ident; /* random number chosen by client. */ VasEBoot_uint16_t seconds; /* seconds since did initial bootstrap. */ VasEBoot_uint16_t flags; VasEBoot_uint32_t client_ip; VasEBoot_uint32_t your_ip; VasEBoot_uint32_t server_ip; VasEBoot_uint32_t gateway_ip; VasEBoot_net_bootp_mac_addr_t mac_addr; char server_name[64]; char boot_file[128]; VasEBoot_uint8_t vendor[0]; } VAS_EBOOT_PACKED; #define VAS_EBOOT_NET_BOOTP_RFC1048_MAGIC_0 0x63 #define VAS_EBOOT_NET_BOOTP_RFC1048_MAGIC_1 0x82 #define VAS_EBOOT_NET_BOOTP_RFC1048_MAGIC_2 0x53 #define VAS_EBOOT_NET_BOOTP_RFC1048_MAGIC_3 0x63 enum { VAS_EBOOT_NET_BOOTP_PAD = 0, VAS_EBOOT_NET_BOOTP_NETMASK = 1, VAS_EBOOT_NET_BOOTP_ROUTER = 3, VAS_EBOOT_NET_BOOTP_DNS = 6, VAS_EBOOT_NET_BOOTP_HOSTNAME = 12, VAS_EBOOT_NET_BOOTP_DOMAIN = 15, VAS_EBOOT_NET_BOOTP_ROOT_PATH = 17, VAS_EBOOT_NET_BOOTP_EXTENSIONS_PATH = 18, VAS_EBOOT_NET_DHCP_REQUESTED_IP_ADDRESS = 50, VAS_EBOOT_NET_DHCP_OVERLOAD = 52, VAS_EBOOT_NET_DHCP_MESSAGE_TYPE = 53, VAS_EBOOT_NET_DHCP_SERVER_IDENTIFIER = 54, VAS_EBOOT_NET_DHCP_PARAMETER_REQUEST_LIST = 55, VAS_EBOOT_NET_BOOTP_CLIENT_ID = 61, VAS_EBOOT_NET_DHCP_TFTP_SERVER_NAME = 66, VAS_EBOOT_NET_DHCP_BOOTFILE_NAME = 67, VAS_EBOOT_NET_BOOTP_CLIENT_UUID = 97, VAS_EBOOT_NET_BOOTP_END = 255 }; struct VasEBoot_net_network_level_interface * VasEBoot_net_configure_by_dhcp_ack (const char *name, struct VasEBoot_net_card *card, VasEBoot_net_interface_flags_t flags, const struct VasEBoot_net_bootp_packet *bp, VasEBoot_size_t size, int is_def, char **device, char **path); VasEBoot_err_t VasEBoot_net_add_ipv4_local (struct VasEBoot_net_network_level_interface *inf, int mask); void VasEBoot_net_process_dhcp (struct VasEBoot_net_buff *nb, struct VasEBoot_net_network_level_interface *iface); int VasEBoot_net_hwaddr_cmp (const VasEBoot_net_link_level_address_t *a, const VasEBoot_net_link_level_address_t *b); int VasEBoot_net_addr_cmp (const VasEBoot_net_network_level_address_t *a, const VasEBoot_net_network_level_address_t *b); /* Currently supported adresses: IPv4: XXX.XXX.XXX.XXX IPv6: XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX */ #define VAS_EBOOT_NET_MAX_STR_ADDR_LEN sizeof ("XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX") /* Currently suppoerted adresses: ethernet: XX:XX:XX:XX:XX:XX */ #define VAS_EBOOT_NET_MAX_STR_HWADDR_LEN (sizeof ("XX:XX:XX:XX:XX:XX")) /* Max VLAN id = 4094 */ #define VAS_EBOOT_NET_MAX_STR_VLAN_LEN (sizeof ("vlanXXXX")) void VasEBoot_net_addr_to_str (const VasEBoot_net_network_level_address_t *target, char *buf); void VasEBoot_net_hwaddr_to_str (const VasEBoot_net_link_level_address_t *addr, char *str); void VasEBoot_net_vlan_to_str (VasEBoot_uint16_t vlantag, char *str); VasEBoot_err_t VasEBoot_env_set_net_property (const char *intername, const char *suffix, const char *value, VasEBoot_size_t len); void VasEBoot_net_poll_cards (unsigned time, int *stop_condition); void VasEBoot_bootp_init (void); void VasEBoot_bootp_fini (void); void VasEBoot_dns_init (void); void VasEBoot_dns_fini (void); void VasEBoot_net_network_level_interface_unregister (struct VasEBoot_net_network_level_interface *inter); void VasEBoot_net_tcp_retransmit (void); void VasEBoot_net_link_layer_add_address (struct VasEBoot_net_card *card, const VasEBoot_net_network_level_address_t *nl, const VasEBoot_net_link_level_address_t *ll, int override); int VasEBoot_net_link_layer_resolve_check (struct VasEBoot_net_network_level_interface *inf, const VasEBoot_net_network_level_address_t *proto_addr); VasEBoot_err_t VasEBoot_net_link_layer_resolve (struct VasEBoot_net_network_level_interface *inf, const VasEBoot_net_network_level_address_t *proto_addr, VasEBoot_net_link_level_address_t *hw_addr); VasEBoot_err_t VasEBoot_net_dns_lookup (const char *name, const struct VasEBoot_net_network_level_address *servers, VasEBoot_size_t n_servers, VasEBoot_size_t *naddresses, struct VasEBoot_net_network_level_address **addresses, int cache); VasEBoot_err_t VasEBoot_net_add_dns_server (const struct VasEBoot_net_network_level_address *s); void VasEBoot_net_remove_dns_server (const struct VasEBoot_net_network_level_address *s); VasEBoot_err_t VasEBoot_net_search_config_file (char *config, VasEBoot_size_t config_buf_len); extern char *VasEBoot_net_default_server; #define VAS_EBOOT_NET_TRIES 40 #define VAS_EBOOT_NET_INTERVAL 400 #define VAS_EBOOT_NET_INTERVAL_ADDITION 20 #define VLANTAG_IDENTIFIER 0x8100 #endif /* ! VAS_EBOOT_NET_HEADER */