summaryrefslogtreecommitdiff
path: root/source3/lib/interface.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-10-25 18:28:36 -0700
committerJeremy Allison <jra@samba.org>2007-10-25 18:28:36 -0700
commit6128d116b3f09ce0b055d2df89b2f7282185782e (patch)
tree4ad151c7224422b1c8f4e1cdca1ffba3d29391f0 /source3/lib/interface.c
parent922db252728b6a9cf72f463a7ce9d5c13f04f5f8 (diff)
downloadsamba-6128d116b3f09ce0b055d2df89b2f7282185782e.tar.gz
samba-6128d116b3f09ce0b055d2df89b2f7282185782e.tar.bz2
samba-6128d116b3f09ce0b055d2df89b2f7282185782e.zip
Fix resolve name to resolve IPv6 addresses of link-local%ifaddr
Jeremy. (This used to be commit e6609cab732d5cd5cc9a5ae50aee15147f2ec6ec)
Diffstat (limited to 'source3/lib/interface.c')
-rw-r--r--source3/lib/interface.c117
1 files changed, 23 insertions, 94 deletions
diff --git a/source3/lib/interface.c b/source3/lib/interface.c
index 49bbceceb7..9d073bc08c 100644
--- a/source3/lib/interface.c
+++ b/source3/lib/interface.c
@@ -88,6 +88,29 @@ bool is_local_net(const struct sockaddr_storage *from)
return false;
}
+#if defined(HAVE_IPV6)
+void setup_linklocal_scope_id(struct sockaddr_storage *pss)
+{
+ struct interface *i;
+ for (i=local_interfaces;i;i=i->next) {
+ if (addr_equal(&i->ip,pss)) {
+ struct sockaddr_in6 *psa6 =
+ (struct sockaddr_in6 *)pss;
+ psa6->sin6_scope_id = if_nametoindex(i->name);
+ return;
+ }
+ }
+ for (i=local_interfaces;i;i=i->next) {
+ if (same_net(pss, &i->ip, &i->netmask)) {
+ struct sockaddr_in6 *psa6 =
+ (struct sockaddr_in6 *)pss;
+ psa6->sin6_scope_id = if_nametoindex(i->name);
+ return;
+ }
+ }
+}
+#endif
+
/****************************************************************************
Check if a packet is from a local (known) net.
**************************************************************************/
@@ -326,100 +349,6 @@ static void add_interface(const struct iface_struct *ifs)
}
/****************************************************************************
- Create a struct sockaddr_storage with the netmask bits set to 1.
-****************************************************************************/
-
-bool make_netmask(struct sockaddr_storage *pss_out,
- const struct sockaddr_storage *pss_in,
- unsigned long masklen)
-{
- *pss_out = *pss_in;
- /* Now apply masklen bits of mask. */
-#if defined(HAVE_IPV6)
- if (pss_in->ss_family == AF_INET6) {
- char *p = (char *)&((struct sockaddr_in6 *)pss_out)->sin6_addr;
- unsigned int i;
-
- if (masklen > 128) {
- return false;
- }
- for (i = 0; masklen >= 8; masklen -= 8, i++) {
- *p++ = 0xff;
- }
- /* Deal with the partial byte. */
- *p++ &= (0xff & ~(0xff>>masklen));
- i++;
- for (;i < sizeof(struct in6_addr); i++) {
- *p++ = '\0';
- }
- return true;
- }
-#endif
- if (pss_in->ss_family == AF_INET) {
- if (masklen > 32) {
- return false;
- }
- ((struct sockaddr_in *)pss_out)->sin_addr.s_addr =
- htonl(((0xFFFFFFFFL >> masklen) ^ 0xFFFFFFFFL));
- return true;
- }
- return false;
-}
-
-/****************************************************************************
- Create a struct sockaddr_storage set to the broadcast or network adress from
- an incoming sockaddr_storage.
-****************************************************************************/
-
-static void make_bcast_or_net(struct sockaddr_storage *pss_out,
- const struct sockaddr_storage *pss_in,
- const struct sockaddr_storage *nmask,
- bool make_bcast)
-{
- unsigned int i = 0, len = 0;
- char *pmask = NULL;
- char *p = NULL;
- *pss_out = *pss_in;
-
- /* Set all zero netmask bits to 1. */
-#if defined(HAVE_IPV6)
- if (pss_in->ss_family == AF_INET6) {
- p = (char *)&((struct sockaddr_in6 *)pss_out)->sin6_addr;
- pmask = (char *)&((struct sockaddr_in6 *)nmask)->sin6_addr;
- len = 16;
- }
-#endif
- if (pss_in->ss_family == AF_INET) {
- p = (char *)&((struct sockaddr_in *)pss_out)->sin_addr;
- pmask = (char *)&((struct sockaddr_in *)nmask)->sin_addr;
- len = 4;
- }
-
- for (i = 0; i < len; i++, p++, pmask++) {
- if (make_bcast) {
- *p = (*p & *pmask) | (*pmask ^ 0xff);
- } else {
- /* make_net */
- *p = (*p & *pmask);
- }
- }
-}
-
-static void make_bcast(struct sockaddr_storage *pss_out,
- const struct sockaddr_storage *pss_in,
- const struct sockaddr_storage *nmask)
-{
- make_bcast_or_net(pss_out, pss_in, nmask, true);
-}
-
-static void make_net(struct sockaddr_storage *pss_out,
- const struct sockaddr_storage *pss_in,
- const struct sockaddr_storage *nmask)
-{
- make_bcast_or_net(pss_out, pss_in, nmask, false);
-}
-
-/****************************************************************************
Interpret a single element from a interfaces= config line.
This handles the following different forms: