diff --git a/Socket/Protocols/INet/INet6Address.cci b/Socket/Protocols/INet/INet6Address.cci
index 408d0ac15b7b74727745aebc3bad6318287ef288..1e71471a2463410a0fcd20bf9f9382cd4330844a 100644
--- a/Socket/Protocols/INet/INet6Address.cci
+++ b/Socket/Protocols/INet/INet6Address.cci
@@ -127,7 +127,7 @@ prefix_ bool senf::INet6Address::unicast()
 prefix_ bool senf::INet6Address::multicast()
     const
 {
-    return (*this)[0] == 0xFFu;
+    return (*this)[0] == 0xFFu || inet4Mapped() && inet4address().multicast();
 }
 
 prefix_ senf::INet6Address::ScopeId senf::INet6Address::scope()
diff --git a/Socket/Protocols/INet/INet6Address.hh b/Socket/Protocols/INet/INet6Address.hh
index 1beecf9484544bc376ae21bcbed86dd94b6fca07..383f87f4fcc6149889d0c75a9edb1b19aad04b06 100644
--- a/Socket/Protocols/INet/INet6Address.hh
+++ b/Socket/Protocols/INet/INet6Address.hh
@@ -216,6 +216,12 @@ namespace senf {
 
         bool unicast() const;           ///< \c true, if address is unicast
         bool multicast() const;         ///< \c true, if address is multicast
+                                        /**< To support a linux specific extension, INet4 multicast
+                                             addressed mapped to INet6 are also interpreted as
+                                             multicast addresses. This is NOT part of the standard,
+                                             however the standard officially only allows unicast v4
+                                             addresses to be mapped to v6 so this does not collide
+                                             with any standard conforming use. */
 
         ScopeId scope() const;          ///< Get address's scope
                                         /**< The scope of an address is one of the \ref ScopeId
diff --git a/Socket/Protocols/INet/INetAddressing.cc b/Socket/Protocols/INet/INetAddressing.cc
index d49f4dee213b1a961916617dd45a01ce8258c064..d3c4e3612abbd110f5d64d9063feca136798f064 100644
--- a/Socket/Protocols/INet/INetAddressing.cc
+++ b/Socket/Protocols/INet/INetAddressing.cc
@@ -89,12 +89,12 @@ prefix_ senf::INet6SocketAddress::INet6SocketAddress(std::string const & addr,
     //             or: host ":" port
     //             or: port
 
-    static boost::regex const addressRx ("(?:(?:\\[([a-f0-9A-F:]+)(?:%(.+))?\\]|(.+)):)?([0-9]+)");
+    static boost::regex const addressRx ("(?:(?:\\[([^%]+)(?:%(.+))?\\]|(.+)):)?([0-9]+)");
     // Subexpression numbers:
-    enum { NumericAddr = 1,
-           ZoneId      = 2,
-           Hostname    = 3,
-           Port        = 4 };
+    enum { Address  = 1,
+           ZoneId   = 2,
+           Hostname = 3,
+           Port     = 4 };
     
     boost::smatch match;
     if (! regex_match(addr, match, addressRx))
@@ -105,9 +105,9 @@ prefix_ senf::INet6SocketAddress::INet6SocketAddress(std::string const & addr,
 
     sockaddr_.sin6_port = htons(boost::lexical_cast<boost::uint16_t>(match[Port]));
 
-    if (match[NumericAddr].matched || match[Hostname].matched) {
+    if (match[Address].matched || match[Hostname].matched) {
         INet6Address a (INet6Address::from_string(
-                            match[NumericAddr].matched ? match[NumericAddr] : match[Hostname],
+                            match[Address].matched ? match[Address] : match[Hostname],
                             resolve));
         std::copy(a.begin(), a.end(), &sockaddr_.sin6_addr.s6_addr[0]);
     }
diff --git a/Socket/Protocols/INet/MulticastSocketProtocol.cc b/Socket/Protocols/INet/MulticastSocketProtocol.cc
index 535dc2fc760cadc20e16bb98bcf6f7946b8fa868..dca071e243781b09c2f531f32541747797d590a6 100644
--- a/Socket/Protocols/INet/MulticastSocketProtocol.cc
+++ b/Socket/Protocols/INet/MulticastSocketProtocol.cc
@@ -121,7 +121,7 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address co
 }
 
 prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address const & mcAddr,
-                                                           INet4Address const & localAddr)
+                                                                 INet4Address const & localAddr)
     const
 {
     struct ip_mreqn mreqn;
@@ -133,7 +133,7 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address co
 }
 
 prefix_ void senf::INet4MulticastSocketProtocol::mcAddMembership(INet4Address const & mcAddr,
-                                                           std::string const & iface)
+                                                                 std::string const & iface)
     const
 {
     struct ip_mreqn mreqn;
@@ -158,7 +158,7 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address c
 }
 
 prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address const & mcAddr,
-                                                            INet4Address const & localAddr)
+                                                                  INet4Address const & localAddr)
     const
 {
     struct ip_mreqn mreqn;
@@ -170,7 +170,7 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address c
 }
 
 prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address const & mcAddr,
-                                                            std::string const & iface)
+                                                                  std::string const & iface)
     const
 {
     struct ip_mreqn mreqn;
@@ -189,47 +189,91 @@ prefix_ void senf::INet4MulticastSocketProtocol::mcDropMembership(INet4Address c
 prefix_ void senf::INet6MulticastSocketProtocol::mcAddMembership(INet6Address const & mcAddr)
     const
 {
-    struct ipv6_mreq mreqn;
-    std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
-    mreqn.ipv6mr_interface = 0;
-    if (::setsockopt(fd(),SOL_IPV6,IPV6_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
-        SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IPV6_ADD_MEMBERSHIP");
+    if (mcAddr.inet4Mapped()) {
+        struct ip_mreqn mreqn;
+        mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr();
+        mreqn.imr_address.s_addr = htons(INADDR_ANY);
+        mreqn.imr_ifindex = 0;
+        if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
+            SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IP_ADD_MEMBERSHIP)");
+    }
+    else {
+        struct ipv6_mreq mreqn;
+        std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
+        mreqn.ipv6mr_interface = 0;
+        if (::setsockopt(fd(),SOL_IPV6,IPV6_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
+            SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IPV6_ADD_MEMBERSHIP");
+    }
 }
 
 prefix_ void senf::INet6MulticastSocketProtocol::mcAddMembership(INet6Address const & mcAddr,
-                                                           std::string const & iface)
+                                                                 std::string const & iface)
 {
-    struct ipv6_mreq mreqn;
-    std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
-    mreqn.ipv6mr_interface = if_nametoindex(iface.c_str());
-    if (mreqn.ipv6mr_interface == 0)
-        throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
-    if (::setsockopt(fd(),SOL_IPV6,IPV6_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
-        SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IPV6_ADD_MEMBERSHIP");
+    if (mcAddr.inet4Mapped()) {
+        struct ip_mreqn mreqn;
+        mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr();
+        mreqn.imr_address.s_addr = htons(INADDR_ANY);
+        mreqn.imr_ifindex = if_nametoindex(iface.c_str());
+        if (mreqn.imr_ifindex == 0)
+            throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
+        if (::setsockopt(fd(),SOL_IP,IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
+            SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IP_ADD_MEMBERSHIP");
+    }
+    else {
+        struct ipv6_mreq mreqn;
+        std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
+        mreqn.ipv6mr_interface = if_nametoindex(iface.c_str());
+        if (mreqn.ipv6mr_interface == 0)
+            throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
+        if (::setsockopt(fd(),SOL_IPV6,IPV6_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
+            SENF_THROW_SYSTEM_EXCEPTION("::setsockopt(IPV6_ADD_MEMBERSHIP");
+    }
 }
 
 prefix_ void senf::INet6MulticastSocketProtocol::mcDropMembership(INet6Address const & mcAddr)
     const
 {
-    struct ipv6_mreq mreqn;
-    std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
-    mreqn.ipv6mr_interface = 0;
-    if (::setsockopt(fd(),SOL_IPV6,IPV6_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
-        SENF_THROW_SYSTEM_EXCEPTION("");
+    if (mcAddr.inet4Mapped()) {
+        struct ip_mreqn mreqn;
+        mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr();
+        mreqn.imr_address.s_addr = htons(INADDR_ANY);
+        mreqn.imr_ifindex = 0;
+        if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
+            SENF_THROW_SYSTEM_EXCEPTION("");
+    }
+    else {
+        struct ipv6_mreq mreqn;
+        std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
+        mreqn.ipv6mr_interface = 0;
+        if (::setsockopt(fd(),SOL_IPV6,IPV6_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
+            SENF_THROW_SYSTEM_EXCEPTION("");
+    }
 }
 
 prefix_ void
 senf::INet6MulticastSocketProtocol::mcDropMembership(INet6Address const & mcAddr,
-                                               std::string const & iface)
+                                                     std::string const & iface)
     const
 {
-    struct ipv6_mreq mreqn;
-    std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
-    mreqn.ipv6mr_interface = if_nametoindex(iface.c_str());
-    if (mreqn.ipv6mr_interface == 0)
-        throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
-    if (::setsockopt(fd(),SOL_IPV6,IPV6_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
-        SENF_THROW_SYSTEM_EXCEPTION("");
+    if (mcAddr.inet4Mapped()) {
+        struct ip_mreqn mreqn;
+        mreqn.imr_multiaddr.s_addr = mcAddr.inet4address().inaddr();
+        mreqn.imr_address.s_addr = htons(INADDR_ANY);
+        mreqn.imr_ifindex = if_nametoindex(iface.c_str());
+        if (mreqn.imr_ifindex == 0)
+            throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
+        if (::setsockopt(fd(),SOL_IP,IP_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
+            SENF_THROW_SYSTEM_EXCEPTION("");
+    }
+    else {
+        struct ipv6_mreq mreqn;
+        std::copy(mcAddr.begin(), mcAddr.end(), mreqn.ipv6mr_multiaddr.s6_addr);
+        mreqn.ipv6mr_interface = if_nametoindex(iface.c_str());
+        if (mreqn.ipv6mr_interface == 0)
+            throw SystemException("::if_nametoindex()",ENOENT SENF_EXC_DEBUGINFO);
+        if (::setsockopt(fd(),SOL_IPV6,IPV6_DROP_MEMBERSHIP,&mreqn,sizeof(mreqn)) < 0)
+            SENF_THROW_SYSTEM_EXCEPTION("");
+    }
 }
 
 ///////////////////////////////cc.e////////////////////////////////////////
diff --git a/Socket/Protocols/INet/MulticastSocketProtocol.hh b/Socket/Protocols/INet/MulticastSocketProtocol.hh
index e8249ce003fc1b41481de2992b176c82ce944653..0de6997b53de6e33698765d4c97ca6054d657b63 100644
--- a/Socket/Protocols/INet/MulticastSocketProtocol.hh
+++ b/Socket/Protocols/INet/MulticastSocketProtocol.hh
@@ -128,6 +128,9 @@ namespace senf {
     };
 
     /** \brief Multicast protocol facet for INet6 addressable multicast enabled sockets
+
+        This implementation supports INet6 mapped INet4 multicast addresses. This is a linux
+        specific extension and NOT part of the relevant RFCs.
      */
     class INet6MulticastSocketProtocol
         : public MulticastSocketProtocol
@@ -139,14 +142,6 @@ namespace senf {
                                              groups received. The group is joined on the default
                                              interface.
                                              \param[in] mcAddr address of group to join */
-        void mcAddMembership(INet6Address const & mcAddr, INet6Address const & localAddr) 
-            const;
-                                        ///< join multicast group on a specific interface
-                                        /**< This member will add \a mcAddr to the list of multicast
-                                             groups received. The group is joined on the interface
-                                             with the given local address.
-                                             \param[in] mcAddr address of group to join
-                                             \param[in] localAddr address of interface to join on */
         void mcAddMembership(INet6Address const & mcAddr, std::string const & iface);
                                         ///< join multicast group on a specific interface
                                         /**< This member will add \a mcAddr to the list of multicast
@@ -161,15 +156,6 @@ namespace senf {
                                              multicast groups received. The group is left from the
                                              default interface.
                                              \param[in] mcAddr address of group to leave */
-        void mcDropMembership(INet6Address const & mcAddr, INet6Address const & localAddr) 
-            const;
-                                        ///< leave multicast group on a specific interface
-                                        /**< This member will remove \a mcAddr from the list of
-                                             multicast groups received. The group is left from the
-                                             interface with the given local address.
-                                             \param[in] mcAddr address of group to leave
-                                             \param[in] localAddr address of interface to leave
-                                                 from */
         void mcDropMembership(INet6Address const & mcAddr, std::string const & iface) 
             const;
                                         ///< leave multicast group on a specific interface
diff --git a/senf.dict b/senf.dict
index f02a484d6c58582798b69311ae4dd1973bef553b..e8d59567db1908f87c7a774cef40b06de10835f7 100644
--- a/senf.dict
+++ b/senf.dict
@@ -41,6 +41,7 @@ BerliOS
 bitfield
 bool
 boostfn
+broadcastEnabled
 bund
 calculateChecksum
 callables
@@ -209,6 +210,7 @@ iberty
 IDE
 IdleEvent
 ietf
+iface
 ifndef
 ih
 impl
@@ -262,9 +264,11 @@ libSocket
 libUtils
 LINKFLAGS
 LinkScope
+linux
 ListB
 ListN
 ListPolicy
+localAddr
 localhost
 loopback
 mac
@@ -272,6 +276,10 @@ MACAddress
 MACAddressParser
 mainpage
 manualparse
+mcAddMembership
+mcAddr
+mcDropMembership
+mcLoop
 mem
 memberfn
 mixin
@@ -279,6 +287,7 @@ mkdir
 MPEGDVBBundle
 mpp
 multicast
+MulticastSocketProtocol
 MyClass
 mycommand
 mydir
@@ -412,6 +421,7 @@ RegistrationProxy
 repos
 rerference
 rfc
+RFCs
 RO
 RP
 SafePacketParser