diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/sockopt.c | 33 | ||||
-rw-r--r-- | lib/sockopt.h | 28 |
2 files changed, 61 insertions, 0 deletions
diff --git a/lib/sockopt.c b/lib/sockopt.c index f8fa946e..985c3a38 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -480,3 +480,36 @@ sockopt_iphdrincl_swab_systoh (struct ip *iph) iph->ip_id = ntohs(iph->ip_id); } + +#if defined(HAVE_TCP_MD5SIG) +int +sockopt_tcp_signature (int sock, struct sockaddr_in *sin, const char *password) +{ + int keylen = password ? strlen(password) : 0; + +#if defined(GNU_LINUX) + + struct tcp_md5sig md5sig; + + bzero ((char *)&md5sig, sizeof(md5sig)); + memcpy (&md5sig.tcpm_addr, sin, sizeof(*sin)); + md5sig.tcpm_keylen = keylen; + if (keylen) + memcpy (md5sig.tcpm_key, password, keylen); + + return setsockopt (sock, IPPROTO_TCP, TCP_MD5SIG, &md5sig, sizeof md5sig); + +#else /* !GNU_LINUX */ + + int enable = keylen ? (TCP_SIG_SPI_BASE + sin->sin_port) : 0; + + /* + * XXX Need to do PF_KEY operation here to add/remove an SA entry, + * and add/remove an SP entry for this peer's packet flows also. + */ + return setsockopt (sock, IPPROTO_TCP, TCP_MD5SIG, &enable, + sizeof(enable)); + +#endif /* !GNU_LINUX */ +} +#endif /* HAVE_TCP_MD5SIG */ diff --git a/lib/sockopt.h b/lib/sockopt.h index ebb71430..158f17ac 100644 --- a/lib/sockopt.h +++ b/lib/sockopt.h @@ -98,4 +98,32 @@ extern int getsockopt_ifindex (int, struct msghdr *); extern void sockopt_iphdrincl_swab_htosys (struct ip *iph); extern void sockopt_iphdrincl_swab_systoh (struct ip *iph); +#if defined(HAVE_TCP_MD5SIG) + +#if defined(GNU_LINUX) && !defined(TCP_MD5SIG) + +/* XXX these will come from <linux/tcp.h> eventually */ + +#define TCP_MD5SIG 14 +#define TCP_MD5SIG_MAXKEYLEN 80 + +struct tcp_md5sig { + struct sockaddr_storage tcpm_addr; /* address associated */ + __u16 __tcpm_pad1; /* zero */ + __u16 tcpm_keylen; /* key length */ + __u32 __tcpm_pad2; /* zero */ + __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* key (binary) */ +}; + +#endif /* defined(GNU_LINUX) && !defined(TCP_MD5SIG) */ + +#if !defined(GNU_LINUX) && !defined(TCP_SIG_SPI_BASE) +#define TCP_SIG_SPI_BASE 1000 /* XXX this will go away */ +#endif + +extern int sockopt_tcp_signature(int sock, struct sockaddr_in *sin, + const char *password); + +#endif /* HAVE_TCP_MD5SIG */ + #endif /*_ZEBRA_SOCKOPT_H */ |