PageRenderTime 58ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 0ms

/uClinux-dist/user/sendip/ipv6.c

https://bitbucket.org/__wp__/mb-linux-msli
C | 131 lines | 111 code | 11 blank | 9 comment | 11 complexity | 700c446b40c4e8f2b1bc7458830d8739 MD5 | raw file
Possible License(s): AGPL-3.0, GPL-2.0, LGPL-2.0, MPL-2.0, ISC, BSD-3-Clause, LGPL-2.1, MPL-2.0-no-copyleft-exception, 0BSD, CC-BY-SA-3.0, GPL-3.0, LGPL-3.0, AGPL-1.0, Unlicense
  1. /* ipv6.c - sendip IPv6 code
  2. * Taken from code by Antti Tuominen <ajtuomin@tml.hut.fi>
  3. * ChangeLog since 2.0 release:
  4. * 09/08/2002 Setting src/dst now works (Pekka Savola <pekkas@netcore.fi>)
  5. */
  6. #include <sys/types.h>
  7. #include <sys/socket.h>
  8. #include <netinet/in.h>
  9. #include <netdb.h>
  10. #include <arpa/inet.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include "sendip_module.h"
  14. #include "ipv6.h"
  15. /* Character that identifies our options
  16. */
  17. const char opt_char='6';
  18. sendip_data *initialize(void) {
  19. sendip_data *ret = malloc(sizeof(sendip_data));
  20. ipv6_header *ipv6 = malloc(sizeof(ipv6_header));
  21. memset(ipv6,0,sizeof(ipv6_header));
  22. ret->alloc_len = sizeof(ipv6_header);
  23. ret->data = (void *)ipv6;
  24. ret->modified=0;
  25. return ret;
  26. }
  27. bool set_addr(char *hostname, sendip_data *pack) {
  28. ipv6_header *ipv6 = (ipv6_header *)pack->data;
  29. struct hostent *host = gethostbyname2(hostname,AF_INET6);
  30. if(!(pack->modified & IPV6_MOD_SRC)) {
  31. ipv6->ip6_src = in6addr_loopback;
  32. }
  33. if(!(pack->modified & IPV6_MOD_DST)) {
  34. if(host==NULL) return FALSE;
  35. if(host->h_length != sizeof(ipv6->ip6_dst)) {
  36. fprintf(stderr,"IPV6 destination address is the wrong size!!!");
  37. return FALSE;
  38. }
  39. memcpy(&(ipv6->ip6_dst),host->h_addr,host->h_length);
  40. }
  41. return TRUE;
  42. }
  43. bool do_opt(char *opt, char *arg, sendip_data *pack) {
  44. ipv6_header *hdr = (ipv6_header *)pack->data;
  45. struct in6_addr addr;
  46. switch(opt[1]) {
  47. case 'f':
  48. /* TODO : This looks byte-order dependant */
  49. hdr->ip6_flow |= htonl((u_int32_t)strtoul(arg, (char **)NULL, 0) & 0xFFF00000);
  50. pack->modified |= IPV6_MOD_FLOW;
  51. break;
  52. case 'v':
  53. hdr->ip6_vfc &= 0x0F;
  54. hdr->ip6_vfc |= (u_int8_t)(strtoul(arg, (char **)NULL, 0) &0x0F) << 4;
  55. pack->modified |= IPV6_MOD_VERSION;
  56. break;
  57. case 'p':
  58. hdr->ip6_vfc &= 0xF0;
  59. hdr->ip6_vfc |= (u_int8_t)strtoul(arg, (char **)NULL, 0) & 0x0F;
  60. pack->modified |= IPV6_MOD_PRIORITY;
  61. break;
  62. case 't':
  63. /* TODO : This looks byte-order dependant */
  64. hdr->ip6_flow |= htonl(((u_int32_t)strtoul(arg, (char **)NULL, 0) << 20) & 0x0F000000);
  65. pack->modified |= IPV6_MOD_FLOW;
  66. break;
  67. case 'l':
  68. hdr->ip6_plen = htons((u_int16_t)strtoul(arg, (char **)NULL, 0));
  69. pack->modified |= IPV6_MOD_PLEN;
  70. break;
  71. case 'h':
  72. hdr->ip6_hlim = (u_int8_t)strtoul(arg, (char **)NULL, 0);
  73. pack->modified |= IPV6_MOD_HLIM;
  74. break;
  75. case 'n':
  76. hdr->ip6_nxt = (u_int8_t)strtoul(arg, (char **)NULL, 0);
  77. pack->modified |= IPV6_MOD_NXT;
  78. break;
  79. case 's':
  80. if (inet_pton(AF_INET6, arg, &addr)) {
  81. memcpy(&hdr->ip6_src, &addr, sizeof(struct in6_addr));
  82. }
  83. pack->modified |= IPV6_MOD_SRC;
  84. break;
  85. case 'd':
  86. if (inet_pton(AF_INET6, arg, &addr)) {
  87. memcpy(&hdr->ip6_dst, &addr, sizeof(struct in6_addr));
  88. }
  89. pack->modified |= IPV6_MOD_DST;
  90. break;
  91. }
  92. return TRUE;
  93. }
  94. bool finalize(char *hdrs, sendip_data *headers[], sendip_data *data,
  95. sendip_data *pack) {
  96. ipv6_header *ipv6 = (ipv6_header *)pack->data;
  97. if(!(pack->modified&IPV6_MOD_VERSION)) {
  98. ipv6->ip6_vfc &= 0x0F;
  99. ipv6->ip6_vfc |= (6 << 4);
  100. }
  101. if(!(pack->modified&IPV6_MOD_PLEN)) {
  102. ipv6->ip6_plen = htons(data->alloc_len);
  103. }
  104. if(!(pack->modified&IPV6_MOD_NXT)) {
  105. ipv6->ip6_nxt = (u_int8_t)IPPROTO_NONE;
  106. }
  107. if(!(pack->modified&IPV6_MOD_HLIM)) {
  108. ipv6->ip6_hlim = 32;
  109. }
  110. return TRUE;
  111. }
  112. int num_opts() {
  113. return sizeof(ipv6_opts)/sizeof(sendip_option);
  114. }
  115. sendip_option *get_opts() {
  116. return ipv6_opts;
  117. }
  118. char get_optchar() {
  119. return opt_char;
  120. }