int (*bind)(struct receiver *rx, char **errmsg); /* bind a receiver */
int (*get_src)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve src addr */
int (*get_dst)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve dst addr */
+ void (*set_port)(struct sockaddr_storage *, int port); /* set the port on the address; NULL if not implemented */
};
/* This structure contains all information needed to easily handle a protocol.
int sock_inet4_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_storage *b);
int sock_inet6_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_storage *b);
+void sock_inet_set_port(struct sockaddr_storage *addr, int port);
int sock_inet_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
int sock_inet_is_foreign(int fd, sa_family_t family);
int sock_inet4_make_foreign(int fd);
.bind = sock_inet_bind_receiver,
.get_src = sock_get_src,
.get_dst = sock_inet_get_dst,
+ .set_port = sock_inet_set_port,
};
struct proto_fam proto_fam_inet6 = {
.bind = sock_inet_bind_receiver,
.get_src = sock_get_src,
.get_dst = sock_get_dst,
+ .set_port = sock_inet_set_port,
};
/* PLEASE NOTE for function below:
return memcmp(&a6->sin6_addr, &b6->sin6_addr, sizeof(a6->sin6_addr));
}
+/* Sets the port <port> on IPv4 or IPv6 address <addr>. The address family is
+ * determined from the sockaddr_storage's address family. Nothing is done for
+ * other families.
+ */
+void sock_inet_set_port(struct sockaddr_storage *addr, int port)
+{
+ if (addr->ss_family == AF_INET)
+ ((struct sockaddr_in *)addr)->sin_port = htons(port);
+ else if (addr->ss_family == AF_INET6)
+ ((struct sockaddr_in6 *)addr)->sin6_port = htons(port);
+}
+
/*
* Retrieves the original destination address for the socket <fd> which must be
* of family AF_INET (not AF_INET6), with <dir> indicating if we're a listener