#endif
}
-int sockopt_tcp_signature(int sock, union sockunion *su, const char *password)
+int sockopt_tcp_signature_ext(int sock, union sockunion *su, uint16_t prefixlen,
+ const char *password)
{
+#ifndef HAVE_DECL_TCP_MD5SIG
+ /*
+ * We have been asked to enable MD5 auth for an address, but our
+ * platform doesn't support that
+ */
+ return -2;
+#endif
+
+#ifndef TCP_MD5SIG_EXT
+ /*
+ * We have been asked to enable MD5 auth for a prefix, but our platform
+ * doesn't support that
+ */
+ if (prefixlen > 0)
+ return -2;
+#endif
+
#if HAVE_DECL_TCP_MD5SIG
int ret;
+
+ int optname = TCP_MD5SIG;
#ifndef GNU_LINUX
/*
* XXX Need to do PF_KEY operation here to add/remove an SA entry,
memset(&md5sig, 0, sizeof(md5sig));
memcpy(&md5sig.tcpm_addr, su2, sizeof(*su2));
+
md5sig.tcpm_keylen = keylen;
if (keylen)
memcpy(md5sig.tcpm_key, password, keylen);
sockunion_free(susock);
+
+ /*
+ * Handle support for MD5 signatures on prefixes, if available and
+ * requested. Technically the #ifdef check below is not needed because
+ * if prefixlen > 0 and we don't have support for this feature we would
+ * have already returned by now, but leaving it there to be explicit.
+ */
+#ifdef TCP_MD5SIG_EXT
+ if (prefixlen > 0) {
+ md5sig.tcpm_prefixlen = prefixlen;
+ md5sig.tcpm_flags = TCP_MD5SIG_FLAG_PREFIX;
+ optname = TCP_MD5SIG_EXT;
+ }
+#endif /* TCP_MD5SIG_EXT */
+
#endif /* GNU_LINUX */
- if ((ret = setsockopt(sock, IPPROTO_TCP, TCP_MD5SIG, &md5sig,
+
+ if ((ret = setsockopt(sock, IPPROTO_TCP, optname, &md5sig,
sizeof md5sig))
< 0) {
/* ENOENT is harmless. It is returned when we clear a password
sock, safe_strerror(errno));
}
return ret;
-#else /* HAVE_TCP_MD5SIG */
- return -2;
-#endif /* !HAVE_TCP_MD5SIG */
+#endif /* HAVE_TCP_MD5SIG */
+}
+
+int sockopt_tcp_signature(int sock, union sockunion *su, const char *password)
+{
+ return sockopt_tcp_signature_ext(sock, su, 0, password);
}
extern void sockopt_iphdrincl_swab_systoh(struct ip *iph);
extern int sockopt_tcp_rtt(int);
+
+/*
+ * TCP MD5 signature option. This option allows TCP MD5 to be enabled on
+ * addresses.
+ *
+ * sock
+ * Socket to enable option on.
+ *
+ * su
+ * Sockunion specifying address to enable option on.
+ *
+ * password
+ * MD5 auth password
+ */
extern int sockopt_tcp_signature(int sock, union sockunion *su,
const char *password);
+/*
+ * Extended TCP MD5 signature option. This option allows TCP MD5 to be enabled
+ * on prefixes.
+ *
+ * sock
+ * Socket to enable option on.
+ *
+ * su
+ * Sockunion specifying address (or prefix) to enable option on.
+ *
+ * prefixlen
+ * 0 - su is an address; fall back to non-extended mode
+ * Else - su is a prefix; prefixlen is the mask length
+ *
+ * password
+ * MD5 auth password
+ */
+extern int sockopt_tcp_signature_ext(int sock, union sockunion *su,
+ uint16_t prefixlen, const char *password);
+
#ifdef __cplusplus
}
#endif