*/
extern int v6tov4(struct in_addr *sin_addr, struct in6_addr *sin6_addr);
-/* compare two struct sockaddr_storage and return:
+/* compare two struct sockaddr_storage, including port if <check_port> is true,
+ * and return:
* 0 (true) if the addr is the same in both
* 1 (false) if the addr is not the same in both
+ * -1 (unable) if one of the addr is not AF_INET*
*/
-int ipcmp(struct sockaddr_storage *ss1, struct sockaddr_storage *ss2);
+int ipcmp(struct sockaddr_storage *ss1, struct sockaddr_storage *ss2, int check_port);
/* compare a struct sockaddr_storage to a struct net_addr and return :
* 0 (true) if <addr> is matching <net>
/* applying ADDR changes if required and allowed
* ipcmp returns 0 when both ADDR are the same
*/
- if (ipcmp(&s->addr, &sa) == 0) {
+ if (ipcmp(&s->addr, &sa, 0) == 0) {
chunk_appendf(msg, "no need to change the addr");
goto port;
}
return 0;
}
-/* compare two struct sockaddr_storage and return:
+/* compare two struct sockaddr_storage, including port if <check_port> is true,
+ * and return:
* 0 (true) if the addr is the same in both
* 1 (false) if the addr is not the same in both
* -1 (unable) if one of the addr is not AF_INET*
*/
-int ipcmp(struct sockaddr_storage *ss1, struct sockaddr_storage *ss2)
+int ipcmp(struct sockaddr_storage *ss1, struct sockaddr_storage *ss2, int check_port)
{
if ((ss1->ss_family != AF_INET) && (ss1->ss_family != AF_INET6))
return -1;
switch (ss1->ss_family) {
case AF_INET:
- return memcmp(&((struct sockaddr_in *)ss1)->sin_addr,
+ return (memcmp(&((struct sockaddr_in *)ss1)->sin_addr,
&((struct sockaddr_in *)ss2)->sin_addr,
- sizeof(struct in_addr)) != 0;
+ sizeof(struct in_addr)) != 0) ||
+ (check_port && get_net_port(ss1) != get_net_port(ss2));
case AF_INET6:
- return memcmp(&((struct sockaddr_in6 *)ss1)->sin6_addr,
+ return (memcmp(&((struct sockaddr_in6 *)ss1)->sin6_addr,
&((struct sockaddr_in6 *)ss2)->sin6_addr,
- sizeof(struct in6_addr)) != 0;
+ sizeof(struct in6_addr)) != 0) ||
+ (check_port && get_net_port(ss1) != get_net_port(ss2));
}
return 1;