luat_netdrv_napt.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include "luat_base.h"
  2. #include "luat_netdrv.h"
  3. #include "luat_network_adapter.h"
  4. #ifdef __LUATOS__
  5. #include "luat_netdrv_ch390h.h"
  6. #endif
  7. #include "luat_malloc.h"
  8. #include "luat_netdrv_napt.h"
  9. #include "lwip/pbuf.h"
  10. #include "lwip/ip.h"
  11. #include "lwip/etharp.h"
  12. #include "lwip/icmp.h"
  13. #include "luat_mcu.h"
  14. #define LUAT_LOG_TAG "netdrv.napt"
  15. #include "luat_log.h"
  16. #define ICMP_MAP_SIZE (32)
  17. #define IP_MAP_SIZE (1024)
  18. /* napt icmp id range: 3000-65535 */
  19. #define NAPT_ICMP_ID_RANGE_START 0xBB8
  20. #define NAPT_ICMP_ID_RANGE_END 0xFFFF
  21. int luat_netdrv_gw_adapter_id = -1;
  22. #define u32 uint32_t
  23. #define u16 uint16_t
  24. #define u8 uint8_t
  25. #define NAPT_ETH_HDR_LEN sizeof(struct ethhdr)
  26. #define NAPT_CHKSUM_16BIT_LEN sizeof(u16)
  27. #ifndef __USER_FUNC_IN_RAM__
  28. #define __USER_FUNC_IN_RAM__
  29. #endif
  30. __USER_FUNC_IN_RAM__ int luat_netdrv_napt_pkg_input(int id, uint8_t* buff, size_t len) {
  31. if (luat_netdrv_gw_adapter_id < 0) {
  32. // LLOGD("NAPT 未开启");
  33. return 0; // NAPT没有开启
  34. }
  35. luat_netdrv_t* net = luat_netdrv_get(id);
  36. if (net == NULL || net->netif == NULL) {
  37. LLOGD("网关netif不存在,无法转发");
  38. return 0;
  39. }
  40. if (len < 24 || len > 1600) {
  41. LLOGD("包长度不合法, 拒绝改写 %d", len);
  42. return 0;
  43. }
  44. // 首先, 如果是eth网卡, 需要先判断是不是广播包
  45. napt_ctx_t ctx = {
  46. .buff = buff,
  47. .len = len,
  48. .iphdr = (struct ip_hdr*)(buff + SIZEOF_ETH_HDR),
  49. .eth = (struct eth_hdr*)buff,
  50. .is_wnet = luat_netdrv_gw_adapter_id == id,
  51. .net = net
  52. };
  53. if (net->netif->flags & NETIF_FLAG_ETHARP) {
  54. // LLOGD("是ETH包, 先判断是不是广播包");
  55. if (memcmp(ctx.eth->dest.addr, "\xFF\xFF\xFF\xFF\xFF\xFF", 6) == 0 ||
  56. ctx.eth->dest.addr[0] == 0x01
  57. ) {
  58. // LLOGD("是广播包,不需要执行napt");
  59. return 0;
  60. }
  61. // LLOGD("ETH包 " MACFMT " -> " MACFMT " %04X", MAC_ARG(ctx.eth->src.addr), MAC_ARG(ctx.eth->dest.addr), ctx.eth->type);
  62. if (ctx.eth->type != PP_HTONS(ETHTYPE_IP)) {
  63. // LLOGD("不是IP包, 不需要执行napt");
  64. return 0;
  65. }
  66. }
  67. else {
  68. // LLOGD("不是ETH包, 裸IP包");
  69. ctx.iphdr = (struct ip_hdr*)(buff);
  70. ctx.eth = NULL;
  71. }
  72. // 看来是IP包了, 判断一下版本号
  73. u8_t ipVersion;
  74. ipVersion = IPH_V(ctx.iphdr);
  75. if (ipVersion != 4) {
  76. LLOGD("不是ipv4包, 不需要执行napt");
  77. return 0;
  78. }
  79. if (luat_netdrv_gw_adapter_id != id && ctx.iphdr->dest.addr == ip_addr_get_ip4_u32(&net->netif->ip_addr)) {
  80. // LLOGD("是本网关的包, 不需要执行napt");
  81. return 0;
  82. }
  83. if (IPH_PROTO(ctx.iphdr) != IP_PROTO_UDP && IPH_PROTO(ctx.iphdr) != IP_PROTO_TCP && IPH_PROTO(ctx.iphdr) != IP_PROTO_ICMP) {
  84. LLOGD("不是tcp/udp/icmp包, 不需要执行napt");
  85. return 0;
  86. }
  87. // LLOGD("按协议类型, 使用对应的NAPT修改器进行处理 id %d proto %d", id, IPH_PROTO(ctx.iphdr));
  88. switch (IPH_PROTO(ctx.iphdr))
  89. {
  90. case IP_PROTO_ICMP:
  91. return luat_napt_icmp_handle(&ctx);
  92. case IP_PROTO_TCP:
  93. return luat_napt_tcp_handle(&ctx);
  94. case IP_PROTO_UDP:
  95. return luat_napt_udp_handle(&ctx);
  96. default:
  97. LLOGD("不是tcp/udp/icmp包, 不需要执行napt");
  98. return 0;
  99. }
  100. return 0;
  101. }
  102. static uint8_t napt_buff[1600];
  103. err_t netdrv_ip_input_cb(int id, struct pbuf *p, struct netif *inp) {
  104. if (p->tot_len > 1600) {
  105. return 1;
  106. }
  107. if (p->tot_len < 24) {
  108. return 1;
  109. }
  110. pbuf_copy_partial(p, napt_buff, p->tot_len, 0);
  111. int ret = luat_netdrv_napt_pkg_input(id, napt_buff, p->tot_len);
  112. // LLOGD("napt_pkg_input ret %d", ret);
  113. return ret == 0 ? 1 : 0;
  114. // return 1;
  115. }
  116. // 辅助函数
  117. int luat_netdrv_napt_pkg_input_pbuf(int id, struct pbuf* p) {
  118. if (p == NULL || p->tot_len > 1600) {
  119. return 0;
  120. }
  121. // LLOGD("pbuf情况 total %d len %d", p->tot_len, p->len);
  122. if (p->tot_len == p->len) {
  123. // LLOGD("其实就是单个pbuf");
  124. return luat_netdrv_napt_pkg_input(id, p->payload, p->tot_len);
  125. }
  126. return 0; // lwip继续处理
  127. }