ethernet.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * GRUB -- GRand Unified Bootloader
  3. * Copyright (C) 2010,2011 Free Software Foundation, Inc.
  4. *
  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.
  9. *
  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.
  14. *
  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/>.
  17. */
  18. #include <grub/misc.h>
  19. #include <grub/mm.h>
  20. #include <grub/net/ethernet.h>
  21. #include <grub/net/ip.h>
  22. #include <grub/net/arp.h>
  23. #include <grub/net/netbuff.h>
  24. #include <grub/net.h>
  25. #include <grub/time.h>
  26. #include <grub/net/arp.h>
  27. #define LLCADDRMASK 0x7f
  28. struct etherhdr
  29. {
  30. grub_uint8_t dst[6];
  31. grub_uint8_t src[6];
  32. grub_uint16_t type;
  33. } GRUB_PACKED;
  34. struct llchdr
  35. {
  36. grub_uint8_t dsap;
  37. grub_uint8_t ssap;
  38. grub_uint8_t ctrl;
  39. } GRUB_PACKED;
  40. struct snaphdr
  41. {
  42. grub_uint8_t oui[3];
  43. grub_uint16_t type;
  44. } GRUB_PACKED;
  45. grub_err_t
  46. send_ethernet_packet (struct grub_net_network_level_interface *inf,
  47. struct grub_net_buff *nb,
  48. grub_net_link_level_address_t target_addr,
  49. grub_net_ethertype_t ethertype)
  50. {
  51. struct etherhdr *eth;
  52. grub_err_t err;
  53. COMPILE_TIME_ASSERT (sizeof (*eth) < GRUB_NET_MAX_LINK_HEADER_SIZE);
  54. err = grub_netbuff_push (nb, sizeof (*eth));
  55. if (err)
  56. return err;
  57. eth = (struct etherhdr *) nb->data;
  58. grub_memcpy (eth->dst, target_addr.mac, 6);
  59. grub_memcpy (eth->src, inf->hwaddress.mac, 6);
  60. eth->type = grub_cpu_to_be16 (ethertype);
  61. if (!inf->card->opened)
  62. {
  63. err = GRUB_ERR_NONE;
  64. if (inf->card->driver->open)
  65. err = inf->card->driver->open (inf->card);
  66. if (err)
  67. return err;
  68. inf->card->opened = 1;
  69. }
  70. return inf->card->driver->send (inf->card, nb);
  71. }
  72. grub_err_t
  73. grub_net_recv_ethernet_packet (struct grub_net_buff *nb,
  74. struct grub_net_card *card)
  75. {
  76. struct etherhdr *eth;
  77. struct llchdr *llch;
  78. struct snaphdr *snaph;
  79. grub_net_ethertype_t type;
  80. grub_net_link_level_address_t hwaddress;
  81. grub_net_link_level_address_t src_hwaddress;
  82. grub_err_t err;
  83. eth = (struct etherhdr *) nb->data;
  84. type = grub_be_to_cpu16 (eth->type);
  85. err = grub_netbuff_pull (nb, sizeof (*eth));
  86. if (err)
  87. return err;
  88. if (type <= 1500)
  89. {
  90. llch = (struct llchdr *) nb->data;
  91. type = llch->dsap & LLCADDRMASK;
  92. if (llch->dsap == 0xaa && llch->ssap == 0xaa && llch->ctrl == 0x3)
  93. {
  94. err = grub_netbuff_pull (nb, sizeof (*llch));
  95. if (err)
  96. return err;
  97. snaph = (struct snaphdr *) nb->data;
  98. type = snaph->type;
  99. }
  100. }
  101. hwaddress.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
  102. grub_memcpy (hwaddress.mac, eth->dst, sizeof (hwaddress.mac));
  103. src_hwaddress.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
  104. grub_memcpy (src_hwaddress.mac, eth->src, sizeof (src_hwaddress.mac));
  105. switch (type)
  106. {
  107. /* ARP packet. */
  108. case GRUB_NET_ETHERTYPE_ARP:
  109. grub_net_arp_receive (nb, card);
  110. grub_netbuff_free (nb);
  111. return GRUB_ERR_NONE;
  112. /* IP packet. */
  113. case GRUB_NET_ETHERTYPE_IP:
  114. case GRUB_NET_ETHERTYPE_IP6:
  115. return grub_net_recv_ip_packets (nb, card, &hwaddress, &src_hwaddress);
  116. }
  117. grub_netbuff_free (nb);
  118. return GRUB_ERR_NONE;
  119. }