• OS X(MACOS) C/C++ 遍历系统所有的IP路由表配置。


     以下源实现为遍历MAC苹果电脑系统上配置的所有IP路由表配置,回调 predicate 过滤函数只在 AF_INET(IPV4)的时候跳出,其它时不处理,人们可以根据自己的需求改动。

    无需依赖MAC OS框架库提供的函数,最小依赖才有可能更容易移植代码到 Apple Inc. 其它操作系统平台上面,另外是 MAC OS 平台依赖不容易受高版本限制。

    1. static int FetchAllRouteNtreeStuff(const ppp::function<bool(int interface_index, uint32_t ip, uint32_t gw, uint32_t mask)>& predicate) noexcept /* sysctlbyname("net.route.0.0.dump", buf, &len, NULL, 0) */
    2. {
    3. if (NULL == predicate)
    4. {
    5. return -1;
    6. }
    7. int mib[] = { CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_GATEWAY };
    8. size_t needed = 0;
    9. if (sysctl(mib, arraysizeof(mib), NULL, &needed, NULL, 0) < 0)
    10. {
    11. return -1;
    12. }
    13. std::shared_ptr buffer_managed = ppp::make_shared_alloc(needed);
    14. if (NULL == buffer_managed)
    15. {
    16. return -1;
    17. }
    18. char* buffer = (char*)buffer_managed.get();
    19. if (sysctl(mib, arraysizeof(mib), buffer, &needed, NULL, 0) < 0)
    20. {
    21. return -1;
    22. }
    23. struct rt_msghdr* rtm = NULL;
    24. char* buffer_needed = buffer + needed;
    25. for (char* i = buffer; i < buffer_needed; i += rtm->rtm_msglen)
    26. {
    27. rtm = (struct rt_msghdr*)(i); /* RTAX_NETMASK */
    28. if (rtm->rtm_type != RTM_GET)
    29. {
    30. continue;
    31. }
    32. /* inet_ntop(AF_INET, &sa->sin_addr.s_addr, line, sizeof(line) - 1); */
    33. if (!(rtm->rtm_flags & RTF_UP))
    34. {
    35. continue;
    36. }
    37. /* MAXHOSTNAMELEN; */
    38. if (!(rtm->rtm_flags & RTF_GATEWAY))
    39. {
    40. continue;
    41. }
    42. struct sockaddr* sa_tab[RTAX_MAX];
    43. if (struct sockaddr* sa = (struct sockaddr*)(rtm + 1); NULL != sa)
    44. {
    45. for (int j = 0; j < RTAX_MAX; j++)
    46. {
    47. if (rtm->rtm_addrs & (1 << j))
    48. {
    49. sa_tab[j] = sa;
    50. sa = (struct sockaddr*)((char*)sa + ROUNDUP(sa->sa_len));
    51. }
    52. else
    53. {
    54. sa_tab[j] = NULL;
    55. }
    56. }
    57. }
    58. uint32_t ip = IPEndPoint::AnyAddress;
    59. uint32_t gw = IPEndPoint::AnyAddress;
    60. uint32_t mask = IPEndPoint::AnyAddress;
    61. if (rtm->rtm_addrs & (1 << RTAX_DST))
    62. {
    63. struct sockaddr_in* sa = (struct sockaddr_in*)(sa_tab[RTAX_DST]);
    64. if (sa->sin_family != AF_INET)
    65. {
    66. continue;
    67. }
    68. ip = sa->sin_addr.s_addr;
    69. }
    70. if (rtm->rtm_addrs & (1 << RTAX_GATEWAY))
    71. {
    72. struct sockaddr_in* sa = (struct sockaddr_in*)(sa_tab[RTAX_GATEWAY]);
    73. if (sa->sin_family != AF_INET)
    74. {
    75. continue;
    76. }
    77. gw = sa->sin_addr.s_addr;
    78. }
    79. if (rtm->rtm_addrs & (1 << RTAX_NETMASK))
    80. {
    81. struct sockaddr_in* sa = (struct sockaddr_in*)(sa_tab[RTAX_NETMASK]);
    82. mask = sa->sin_addr.s_addr;
    83. }
    84. if (predicate(rtm->rtm_index, ip, gw, mask))
    85. {
    86. break;
    87. }
    88. }
    89. return 0;
    90. }

  • 相关阅读:
    iOS小技能: 日历的使用(案例:两个时间的比较、获取最近30天的数据)
    大一网页设计期末大作业,HTML+CSS静态网站
    CentOS7安装telnet服务
    Java项目中jar war pom包的区别
    LeetCode 刷题系列 -- 98. 验证二叉搜索树
    c库函数:strrchr使用demo案例
    集成应用签名服务,加入签名计划后,想要删除AGC中托管的应用签名,退出签名计划如何做?应用签名服务常见问题小集合
    Jmeter并发压测数据库的TPC值
    基于STM32+物联网设计的货车重量检测系统(OneNet)
    简单讲解 glm::mat4
  • 原文地址:https://blog.csdn.net/liulilittle/article/details/136171902