Practical.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #include <stdio.h>
  2. #include <netdb.h>
  3. #include <netinet/in.h>
  4. #include <stddef.h>
  5. #include <arpa/inet.h>
  6. #include <string.h>
  7. #include "Practical.h"
  8. int proto_get_num(const char *name) {
  9. struct protoent *protoent = getprotobyname(name);
  10. if (protoent == NULL) {
  11. DieWithSystemMessage("getprotobyname");
  12. }
  13. return protoent->p_proto;
  14. }
  15. void PrintSocketAddress(const struct sockaddr *address, FILE *stream) {
  16. if (address == nullptr || stream == nullptr) {
  17. return;
  18. }
  19. void *numericAddress = nullptr;
  20. char addrBuffer[INET6_ADDRSTRLEN];
  21. in_port_t port;
  22. switch (address->sa_family) {
  23. case AF_INET:
  24. const struct sockaddr_in *const inet_addr = (struct sockaddr_in *) address;
  25. numericAddress = (void *) &inet_addr->sin_addr;
  26. port = ntohs(inet_addr->sin_port);
  27. break;
  28. case AF_INET6:
  29. const struct sockaddr_in6 *const inet6_addr = (struct sockaddr_in6 *) address;
  30. numericAddress = (void *) &inet6_addr->sin6_addr;
  31. port = ntohs(inet6_addr->sin6_port);
  32. break;
  33. default:
  34. fputs("[unkown type]", stream);
  35. return;
  36. }
  37. if (inet_ntop(
  38. address->sa_family,
  39. numericAddress,
  40. addrBuffer,
  41. sizeof(addrBuffer)
  42. )
  43. != nullptr) {
  44. fprintf(stream, "%s", addrBuffer);
  45. if (port != 0) {
  46. fprintf(stream, "-%u", port);
  47. }
  48. } else {
  49. fputs("[invalid address]", stream);
  50. }
  51. }
  52. // Chapter 3 exercise 4
  53. int AF_to_PF(const int af) {
  54. switch (af) {
  55. case AF_UNSPEC:
  56. return PF_UNSPEC;
  57. case AF_LOCAL:
  58. return PF_LOCAL;
  59. case AF_INET:
  60. return PF_INET;
  61. case AF_AX25:
  62. return PF_AX25;
  63. case AF_IPX:
  64. return PF_IPX;
  65. case AF_APPLETALK:
  66. return PF_APPLETALK;
  67. case AF_NETROM:
  68. return PF_NETROM;
  69. case AF_BRIDGE:
  70. return PF_BRIDGE;
  71. case AF_ATMPVC:
  72. return PF_ATMPVC;
  73. case AF_X25:
  74. return PF_X25;
  75. case AF_INET6:
  76. return PF_INET6;
  77. case AF_ROSE:
  78. return PF_ROSE;
  79. case AF_DECnet:
  80. return PF_DECnet;
  81. case AF_NETBEUI:
  82. return PF_NETBEUI;
  83. case AF_SECURITY:
  84. return PF_SECURITY;
  85. case AF_KEY:
  86. return PF_KEY;
  87. case AF_PACKET:
  88. return PF_PACKET;
  89. case AF_ASH:
  90. return PF_ASH;
  91. case AF_ECONET:
  92. return PF_ECONET;
  93. case AF_ATMSVC:
  94. return PF_ATMSVC;
  95. case AF_RDS:
  96. return PF_RDS;
  97. case AF_SNA:
  98. return PF_SNA;
  99. case AF_IRDA:
  100. return PF_IRDA;
  101. case AF_PPPOX:
  102. return PF_PPPOX;
  103. case AF_WANPIPE:
  104. return PF_WANPIPE;
  105. case AF_LLC:
  106. return PF_LLC;
  107. case AF_IB:
  108. return PF_IB;
  109. case AF_MPLS:
  110. return PF_MPLS;
  111. case AF_CAN:
  112. return PF_CAN;
  113. case AF_TIPC:
  114. return PF_TIPC;
  115. case AF_BLUETOOTH:
  116. return PF_BLUETOOTH;
  117. case AF_IUCV:
  118. return PF_IUCV;
  119. case AF_RXRPC:
  120. return PF_RXRPC;
  121. case AF_ISDN:
  122. return PF_ISDN;
  123. case AF_PHONET:
  124. return PF_PHONET;
  125. case AF_IEEE802154:
  126. return PF_IEEE802154;
  127. case AF_CAIF:
  128. return PF_CAIF;
  129. case AF_ALG:
  130. return PF_ALG;
  131. case AF_NFC:
  132. return PF_NFC;
  133. case AF_VSOCK:
  134. return PF_VSOCK;
  135. case AF_KCM:
  136. return PF_KCM;
  137. case AF_QIPCRTR:
  138. return PF_QIPCRTR;
  139. case AF_SMC:
  140. return PF_SMC;
  141. case AF_XDP:
  142. return PF_XDP;
  143. case AF_MCTP:
  144. return PF_MCTP;
  145. case AF_MAX:
  146. return PF_MAX;
  147. }
  148. // Handle entries that (currently) have duplicate values
  149. if (af == AF_UNIX) {
  150. return PF_UNIX;
  151. }
  152. if (af == AF_FILE) {
  153. return PF_FILE;
  154. }
  155. if (af == AF_NETLINK) {
  156. return PF_NETLINK;
  157. }
  158. if (af == AF_ROUTE) {
  159. return PF_ROUTE;
  160. }
  161. DieWithUserMessage("AF_to_PF", "Unkown AF_ value");
  162. return -1; // Unreachable, makes LSP shut up about not returning a value.
  163. }
  164. bool sock_addrs_equal(const struct sockaddr *const a1, const struct sockaddr *const a2) {
  165. if (a1->sa_family != a2->sa_family) {
  166. return false;
  167. }
  168. if (a1->sa_family != AF_INET && a1->sa_family != AF_INET6) {
  169. DieWithUserMessage("Unsupported value for", "a1->sa_family");
  170. }
  171. const size_t addr_size = a1->sa_family == AF_INET
  172. ? sizeof(struct in_addr)
  173. : sizeof(struct in6_addr);
  174. return memcmp(a1->sa_data, a2->sa_data, addr_size) == 0;
  175. }