+}
+
+static int addr_equal(struct sockaddr *a, struct sockaddr *b) {
+ switch (a->sa_family) {
+ case AF_INET:
+ return !memcmp(&((struct sockaddr_in*)a)->sin_addr,
+ &((struct sockaddr_in*)b)->sin_addr,
+ sizeof(struct in_addr));
+ case AF_INET6:
+ return IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6*)a)->sin6_addr,
+ &((struct sockaddr_in6*)b)->sin6_addr);
+ default:
+ /* Must not reach */
+ return 0;
+ }
+}
+
+uint16_t port_get(struct sockaddr *sa) {
+ switch (sa->sa_family) {
+ case AF_INET:
+ return ntohs(((struct sockaddr_in *)sa)->sin_port);
+ case AF_INET6:
+ return ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
+ }
+ return 0;
+}