From: Vladimir 'phcoder' Serbinenko Date: Tue, 20 Dec 2011 17:17:07 +0000 (+0100) Subject: IPv6, TCP, HTTP, ICMP and DNS support. Several cleanups and bugfixes. X-Git-Tag: 2.00~851 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=198e150aafdb732a0629eac1456eed4a2a24c638;p=thirdparty%2Fgrub.git IPv6, TCP, HTTP, ICMP and DNS support. Several cleanups and bugfixes. * grub-core/Makefile.core.def (net): Add net/dns.c, net/tcp.c, net/icmp.c and net/icmp6.c. (http): New module. (priority_queue): Likewise. * grub-core/io/bufio.c: Rewritten. * grub-core/lib/legacy_parse.c (legacy_command): New argument type TYPE_WITH_CONFIGFILE_OPTION. (legacy_commands): Add bootp and dhcp. (is_option): Handle TYPE_WITH_CONFIGFILE_OPTION. (grub_legacy_parse): Likewise. * grub-core/lib/priority_queue.c: New file. * grub-core/net/arp.c: Add missing license header. (arp_find_entry): Removed. (arp_find_entry): Likewise. (grub_net_arp_resolve): Rename to ... (grub_net_arp_send_request): ...this. (grub_net_arp_receive): New card argument. * grub-core/net/bootp.c (parse_dhcp_vendor): Clean up. Set router and DNS server. (grub_net_configure_by_dhcp_ack): Handle routing information. (grub_cmd_bootp): Set checksum. (grub_bootp_init): Remove net_dhcp. * grub-core/net/dns.c: New file. * grub-core/net/drivers/efi/efinet.c (send_card_buffer): Wait for completion. (get_card_packet): Handle allocation. (grub_efinet_findcards): Set mtu. * grub-core/net/drivers/emu/emunet.c: Add missing license header. (get_card_packet): Handle allocation. (emucard): Set mtu. * grub-core/net/drivers/i386/pc/pxe.c (grub_pxe_recv): Handle allocation (GRUB_MOD_INIT): Set mtu. * grub-core/net/drivers/ieee1275/ofnet.c (grub_ofnetcard_data): Remove mtu. (get_card_packet): Handle allocation. (grub_ofnet_findcards): Set mtu. * grub-core/net/ethernet.c (send_ethernet_packet): Add compile time assert. (grub_net_recv_ethernet_packet): Handle IPv6. * grub-core/net/http.c: New file. * grub-core/net/icmp.c: Likewise. * grub-core/net/icmp6.c: Likewise. * grub-core/net/ip.c (ip6addr): New type. (ip6hdr): Likewise. (reassemble): Likewise. (cmp): New function. (reassembles): New variable. (grub_net_ip_chksum): Handle 0xffff sum and unaligned buffers. (id): New variable. (send_fragmented): New function. (grub_net_send_ip_packet): Rename to ... (grub_net_send_ip4_packet): ... this. Send fragmented if needed. Handle non-UDP. (grub_net_recv_ip_packets): Rename to ... (handle_dgram): ... this. Check checksum. Handle non-UDP. (free_rsm): New function. (free_old_fragments): Likewise. (grub_net_recv_ip4_packets): New function. (grub_net_send_ip6_packet): Likewise. (grub_net_send_ip_packet): Likewise. (grub_net_recv_ip6_packets): Likewise. (grub_net_recv_ip_packets): Likewise. * grub-core/net/net.c (grub_net_link_layer_entry): New struct. (LINK_LAYER_CACHE_SIZE): New const. (link_layer_find_entry): New function. (grub_net_link_layer_add_address): Likewise. (grub_net_link_layer_resolve_check): Likewise. (grub_net_link_layer_resolve): Likewise. (grub_net_ipv6_get_slaac): Likewise. (grub_net_ipv6_get_link_local): Likewise. (grub_cmd_ipv6_autoconf): Likewise. (parse_ip): Handle one number representation. (parse_ip6): New functoion. (match_net): Handle IPv6. (grub_net_resolve_address): Handle IPv6 and DNS. (grub_net_resolve_net_address): Handle IPv6. (route_cmp): New function. (grub_net_route_address): Find best route. (grub_net_addr_to_str): Handle IPv6. (grub_net_addr_cmp): New function. (grub_net_add_addr): Register local route. (print_net_address): Handle net address. (grub_net_poll_cards): Retransmit TCP. (grub_net_poll_cards_idle_real): Likewise. (have_ahead): New function. (grub_net_seek_real): Use underlying seek. (GRUB_MOD_INIT): Register net_ipv6_autoconf and init dns. * grub-core/net/tcp.c: New file. * grub-core/net/tftp.c (tftp_data): Add priority_queue. (cmp): New function. (ack): Likewise. (tftp_receive): Handle unordered input. (destroy_pq): New function. (tftp_close): Close pq. * grub-core/net/udp.c: Put missing license header. (grub_net_udp_socket): New function. (udp_socket_register): Likewise. (grub_net_udp_close): Likewise. (grub_net_recv_udp_packet): Check checksum. * include/grub/efi/api.h (grub_efi_simple_network): Add status. * include/grub/misc.h (grub_memchr): New function. * include/grub/net.h (GRUB_NET_*_SIZE): New enum. (grub_net_card_driver): Return buf in recv. (grub_net_slaac_mac_list): New struct. (grub_network_level_protocol_id): Add ipv6. (grub_net_network_level_addr): Likewise. (grub_net_network_level_net_addr): Likewise. (grub_net_app_protocol): Add seek. (grub_net_socket): Removed. (grub_net_sockets): Likewise. (grub_net_socket_register): Likewise. (grub_net_socket_unregister): Likewise. (FOR_NET_SOCKETS): Likewise. (grub_net_add_addr): Add const. (GRUB_NET_BOOTP_*): New enum. (grub_net_addr_cmp): New proto. (GRUB_NET_MAX_STR_ADDR_LEN): Take IPV6 into account. (GRUB_NET_MAX_STR_HWADDR_LEN): New define. (grub_net_hwaddr_to_str): NEw proto. (FOR_NET_NETWORK_LEVEL_INTERFACES): New macro. (FOR_NET_NETWORK_LEVEL_INTERFACES_SAFE): Handle NULL. (grub_dns_init): New proto. (grub_dns_fini): Likewise. (grub_net_tcp_retransmit): Likewise. (grub_net_link_layer_add_address): Likewise. (grub_net_link_layer_resolve_check): Likewise. (grub_net_link_layer_resolve): Likewise. (grub_net_dns_lookup): Likewise. (grub_net_add_dns_server): Likewise. (grub_net_remove_dns_server): Likewise. (GRUB_NET_TRIES): New const. (GRUB_NET_INTERVAL): Likewise. * include/grub/net/arp.h: Mostly rewritten. * include/grub/net/ethernet.h (grub_net_ethertype_t): New enum. * include/grub/net/ip.h: Mostly rewritten. * include/grub/net/netbuff.h: Indent. * include/grub/net/tcp.h: New file. * include/grub/net/udp.h: Mostly rewritten. * include/grub/priority_queue.h: New file. * include/grub/types.h (PRIdGRUB_SSIZE): New define. (grub_swap_bytes64_compile_time): Likewise. (grub_cpu_to_be16_compile_time): Likewise. (grub_cpu_to_be32_compile_time): Likewise. (grub_cpu_to_be64_compile_time): Likewise. (grub_be_to_cpu64_compile_time): Likewise. --- 198e150aafdb732a0629eac1456eed4a2a24c638 diff --cc ChangeLog index 4aacc74b8,4aacc74b8..a2032567b --- a/ChangeLog +++ b/ChangeLog @@@ -1,3 -1,3 +1,153 @@@ ++2011-12-20 Vladimir Serbinenko ++ ++ IPv6, TCP, HTTP, ICMP and DNS support. Several cleanups and bugfixes. ++ ++ * grub-core/Makefile.core.def (net): Add net/dns.c, net/tcp.c, ++ net/icmp.c and net/icmp6.c. ++ (http): New module. ++ (priority_queue): Likewise. ++ * grub-core/io/bufio.c: Rewritten. ++ * grub-core/lib/legacy_parse.c (legacy_command): New argument type ++ TYPE_WITH_CONFIGFILE_OPTION. ++ (legacy_commands): Add bootp and dhcp. ++ (is_option): Handle TYPE_WITH_CONFIGFILE_OPTION. ++ (grub_legacy_parse): Likewise. ++ * grub-core/lib/priority_queue.c: New file. ++ * grub-core/net/arp.c: Add missing license header. ++ (arp_find_entry): Removed. ++ (arp_find_entry): Likewise. ++ (grub_net_arp_resolve): Rename to ... ++ (grub_net_arp_send_request): ...this. ++ (grub_net_arp_receive): New card argument. ++ * grub-core/net/bootp.c (parse_dhcp_vendor): Clean up. ++ Set router and DNS server. ++ (grub_net_configure_by_dhcp_ack): Handle routing information. ++ (grub_cmd_bootp): Set checksum. ++ (grub_bootp_init): Remove net_dhcp. ++ * grub-core/net/dns.c: New file. ++ * grub-core/net/drivers/efi/efinet.c (send_card_buffer): Wait for ++ completion. ++ (get_card_packet): Handle allocation. ++ (grub_efinet_findcards): Set mtu. ++ * grub-core/net/drivers/emu/emunet.c: Add missing license header. ++ (get_card_packet): Handle allocation. ++ (emucard): Set mtu. ++ * grub-core/net/drivers/i386/pc/pxe.c (grub_pxe_recv): Handle allocation ++ (GRUB_MOD_INIT): Set mtu. ++ * grub-core/net/drivers/ieee1275/ofnet.c (grub_ofnetcard_data): Remove ++ mtu. ++ (get_card_packet): Handle allocation. ++ (grub_ofnet_findcards): Set mtu. ++ * grub-core/net/ethernet.c (send_ethernet_packet): Add compile time ++ assert. ++ (grub_net_recv_ethernet_packet): Handle IPv6. ++ * grub-core/net/http.c: New file. ++ * grub-core/net/icmp.c: Likewise. ++ * grub-core/net/icmp6.c: Likewise. ++ * grub-core/net/ip.c (ip6addr): New type. ++ (ip6hdr): Likewise. ++ (reassemble): Likewise. ++ (cmp): New function. ++ (reassembles): New variable. ++ (grub_net_ip_chksum): Handle 0xffff sum and unaligned buffers. ++ (id): New variable. ++ (send_fragmented): New function. ++ (grub_net_send_ip_packet): Rename to ... ++ (grub_net_send_ip4_packet): ... this. Send fragmented if needed. ++ Handle non-UDP. ++ (grub_net_recv_ip_packets): Rename to ... ++ (handle_dgram): ... this. Check checksum. Handle non-UDP. ++ (free_rsm): New function. ++ (free_old_fragments): Likewise. ++ (grub_net_recv_ip4_packets): New function. ++ (grub_net_send_ip6_packet): Likewise. ++ (grub_net_send_ip_packet): Likewise. ++ (grub_net_recv_ip6_packets): Likewise. ++ (grub_net_recv_ip_packets): Likewise. ++ * grub-core/net/net.c (grub_net_link_layer_entry): New struct. ++ (LINK_LAYER_CACHE_SIZE): New const. ++ (link_layer_find_entry): New function. ++ (grub_net_link_layer_add_address): Likewise. ++ (grub_net_link_layer_resolve_check): Likewise. ++ (grub_net_link_layer_resolve): Likewise. ++ (grub_net_ipv6_get_slaac): Likewise. ++ (grub_net_ipv6_get_link_local): Likewise. ++ (grub_cmd_ipv6_autoconf): Likewise. ++ (parse_ip): Handle one number representation. ++ (parse_ip6): New functoion. ++ (match_net): Handle IPv6. ++ (grub_net_resolve_address): Handle IPv6 and DNS. ++ (grub_net_resolve_net_address): Handle IPv6. ++ (route_cmp): New function. ++ (grub_net_route_address): Find best route. ++ (grub_net_addr_to_str): Handle IPv6. ++ (grub_net_addr_cmp): New function. ++ (grub_net_add_addr): Register local route. ++ (print_net_address): Handle net address. ++ (grub_net_poll_cards): Retransmit TCP. ++ (grub_net_poll_cards_idle_real): Likewise. ++ (have_ahead): New function. ++ (grub_net_seek_real): Use underlying seek. ++ (GRUB_MOD_INIT): Register net_ipv6_autoconf and init dns. ++ * grub-core/net/tcp.c: New file. ++ * grub-core/net/tftp.c (tftp_data): Add priority_queue. ++ (cmp): New function. ++ (ack): Likewise. ++ (tftp_receive): Handle unordered input. ++ (destroy_pq): New function. ++ (tftp_close): Close pq. ++ * grub-core/net/udp.c: Put missing license header. ++ (grub_net_udp_socket): New function. ++ (udp_socket_register): Likewise. ++ (grub_net_udp_close): Likewise. ++ (grub_net_recv_udp_packet): Check checksum. ++ * include/grub/efi/api.h (grub_efi_simple_network): Add status. ++ * include/grub/misc.h (grub_memchr): New function. ++ * include/grub/net.h (GRUB_NET_*_SIZE): New enum. ++ (grub_net_card_driver): Return buf in recv. ++ (grub_net_slaac_mac_list): New struct. ++ (grub_network_level_protocol_id): Add ipv6. ++ (grub_net_network_level_addr): Likewise. ++ (grub_net_network_level_net_addr): Likewise. ++ (grub_net_app_protocol): Add seek. ++ (grub_net_socket): Removed. ++ (grub_net_sockets): Likewise. ++ (grub_net_socket_register): Likewise. ++ (grub_net_socket_unregister): Likewise. ++ (FOR_NET_SOCKETS): Likewise. ++ (grub_net_add_addr): Add const. ++ (GRUB_NET_BOOTP_*): New enum. ++ (grub_net_addr_cmp): New proto. ++ (GRUB_NET_MAX_STR_ADDR_LEN): Take IPV6 into account. ++ (GRUB_NET_MAX_STR_HWADDR_LEN): New define. ++ (grub_net_hwaddr_to_str): NEw proto. ++ (FOR_NET_NETWORK_LEVEL_INTERFACES): New macro. ++ (FOR_NET_NETWORK_LEVEL_INTERFACES_SAFE): Handle NULL. ++ (grub_dns_init): New proto. ++ (grub_dns_fini): Likewise. ++ (grub_net_tcp_retransmit): Likewise. ++ (grub_net_link_layer_add_address): Likewise. ++ (grub_net_link_layer_resolve_check): Likewise. ++ (grub_net_link_layer_resolve): Likewise. ++ (grub_net_dns_lookup): Likewise. ++ (grub_net_add_dns_server): Likewise. ++ (grub_net_remove_dns_server): Likewise. ++ (GRUB_NET_TRIES): New const. ++ (GRUB_NET_INTERVAL): Likewise. ++ * include/grub/net/arp.h: Mostly rewritten. ++ * include/grub/net/ethernet.h (grub_net_ethertype_t): New enum. ++ * include/grub/net/ip.h: Mostly rewritten. ++ * include/grub/net/netbuff.h: Indent. ++ * include/grub/net/tcp.h: New file. ++ * include/grub/net/udp.h: Mostly rewritten. ++ * include/grub/priority_queue.h: New file. ++ * include/grub/types.h (PRIdGRUB_SSIZE): New define. ++ (grub_swap_bytes64_compile_time): Likewise. ++ (grub_cpu_to_be16_compile_time): Likewise. ++ (grub_cpu_to_be32_compile_time): Likewise. ++ (grub_cpu_to_be64_compile_time): Likewise. ++ (grub_be_to_cpu64_compile_time): Likewise. ++ 2011-12-16 Vladimir Serbinenko * grub-core/commands/i386/pc/drivemap.c (int13slot): Replace diff --cc grub-core/net/ip.c index 642a67f18,b56c9d14a..f3ec74d57 --- a/grub-core/net/ip.c +++ b/grub-core/net/ip.c @@@ -35,34 -37,80 +37,83 @@@ struct iphdr grub_uint8_t protocol; grub_uint16_t chksum; grub_uint32_t src; - grub_uint32_t dest; + grub_uint32_t dest; } __attribute__ ((packed)) ; - struct ip6hdr + enum { - grub_uint8_t version:4, priority:4; - grub_uint8_t flow_lbl[3]; - grub_uint16_t payload_len; - grub_uint8_t nexthdr; - grub_uint8_t hop_limit; - grub_uint8_t saddr[16]; - grub_uint8_t daddr[16]; - } __attribute__ ((packed)); + DONT_FRAGMENT = 0x4000, + MORE_FRAGMENTS = 0x2000, + OFFSET_MASK = 0x1fff + }; + + typedef grub_uint64_t ip6addr[2]; + + struct ip6hdr { + grub_uint32_t version_class_flow; + grub_uint16_t len; + grub_uint8_t protocol; + grub_uint8_t ttl; + ip6addr src; + ip6addr dest; + } __attribute__ ((packed)) ; + + static int + cmp (const void *a__, const void *b__) + { + struct grub_net_buff *a_ = *(struct grub_net_buff **) a__; + struct grub_net_buff *b_ = *(struct grub_net_buff **) b__; + struct iphdr *a = (struct iphdr *) a_->data; + struct iphdr *b = (struct iphdr *) b_->data; + /* We want the first elements to be on top. */ + if ((grub_be_to_cpu16 (a->frags) & OFFSET_MASK) + < (grub_be_to_cpu16 (b->frags) & OFFSET_MASK)) + return +1; + if ((grub_be_to_cpu16 (a->frags) & OFFSET_MASK) + > (grub_be_to_cpu16 (b->frags) & OFFSET_MASK)) + return -1; + return 0; + } + + struct reassemble + { + struct reassemble *next; + grub_uint32_t source; + grub_uint32_t dest; + grub_uint16_t id; + grub_uint8_t proto; + grub_uint64_t last_time; + grub_priority_queue_t pq; + grub_uint8_t *asm_buffer; + grub_size_t total_len; + grub_size_t cur_ptr; + grub_uint8_t ttl; + }; + -struct reassemble *reassembles; ++static struct reassemble *reassembles; grub_uint16_t - grub_net_ip_chksum (void *ipv, int len) + grub_net_ip_chksum (void *ipv, grub_size_t len) { grub_uint16_t *ip = (grub_uint16_t *) ipv; grub_uint32_t sum = 0; - len >>= 1; - while (len--) + for (; len >= 2; len -= 2) + { - sum += grub_be_to_cpu16 (*(ip++)); - if (sum >= 0xFFFF) ++ sum += grub_be_to_cpu16 (grub_get_unaligned16 (ip++)); ++ if (sum > 0xFFFF) + sum -= 0xFFFF; + } + if (len) { - sum += grub_be_to_cpu16 (*(ip++)); + sum += *((grub_uint8_t *) ip) << 8; - if (sum >= 0xFFFF) + if (sum > 0xFFFF) sum -= 0xFFFF; } ++ if (sum >= 0xFFFF) ++ sum -= 0xFFFF; ++ return grub_cpu_to_be16 ((~sum) & 0x0000FFFF); } diff --cc grub-core/net/udp.c index 47a67a967,e26608e36..8ca8ebb0a --- a/grub-core/net/udp.c +++ b/grub-core/net/udp.c @@@ -4,10 -22,46 +22,46 @@@ #include #include - grub_net_socket_t - grub_net_udp_open (char *server, + struct grub_net_udp_socket + { + struct grub_net_udp_socket *next; + + enum { GRUB_NET_SOCKET_START, + GRUB_NET_SOCKET_ESTABLISHED, + GRUB_NET_SOCKET_CLOSED } status; + int in_port; + int out_port; + grub_err_t (*recv_hook) (grub_net_udp_socket_t sock, struct grub_net_buff *nb, + void *recv); + void *recv_hook_data; + grub_net_network_level_address_t out_nla; + grub_net_link_level_address_t ll_target_addr; + struct grub_net_network_level_interface *inf; + }; + -struct grub_net_udp_socket *udp_sockets; ++static struct grub_net_udp_socket *udp_sockets; + + #define FOR_UDP_SOCKETS(var) for (var = udp_sockets; var; var = var->next) + + static inline void + udp_socket_register (grub_net_udp_socket_t sock) + { + grub_list_push (GRUB_AS_LIST_P (&udp_sockets), + GRUB_AS_LIST (sock)); + } + + void + grub_net_udp_close (grub_net_udp_socket_t sock) + { + grub_list_remove (GRUB_AS_LIST_P (&udp_sockets), + GRUB_AS_LIST (sock)); + grub_free (sock); + } + + grub_net_udp_socket_t + grub_net_udp_open (grub_net_network_level_address_t addr, grub_uint16_t out_port, - grub_err_t (*recv_hook) (grub_net_socket_t sock, + grub_err_t (*recv_hook) (grub_net_udp_socket_t sock, struct grub_net_buff *nb, void *data), void *recv_hook_data)