Reading MLDv2 queries using an IPv6 socket

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
1
down vote

favorite












I have mrd6 installed on my raspberry pi. It registers with a local interface (tun0) and periodically transmits MLDv2 queries over it.



According to [RFC3810], MLDv2 message types are a subset of ICMPv6 messages, and are identified in IPv6 packets by a preceding Next Header value of 58 (0x3a). They are sent with a link-local IPv6 Source Address, an IPv6 Hop Limit of 1, and an IPv6 Router Alert option [RFC2711] in a Hop-by-Hop Options header.



I can confirm that I'm seeing these packets periodically over tun0:



pi@machine:~ $ sudo tcpdump -i tun0 ip6 -vv -XX

01:22:52.125915 IP6 (flowlabel 0x71df6, hlim 1, next-header Options (0)
payload length: 36)
fe80::69bf:be2d:e087:9921 > ip6-allnodes: HBH (rtalert: 0x0000) (padn)
[icmp6 sum ok] ICMP6, multicast listener query v2 [max resp delay=10000]
[gaddr :: robustness=2 qqi=125]
0x0000: 6007 1df6 0024 0001 fe80 0000 0000 0000 `....$..........
0x0010: 69bf be2d e087 9921 ff02 0000 0000 0000 i..-...!........
0x0020: 0000 0000 0000 0001 3a00 0502 0000 0100 ........:.......
0x0030: 8200 b500 2710 0000 0000 0000 0000 0000 ....'...........
0x0040: 0000 0000 0000 0000 027d 0000 .........}..


I have a socket set up in my application on tun0 as follows, since I expect these to be ICMP packets:



int fd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); // ICMP

// ... bind this socket to tun0

int interfaceIndex = // tun0 interface Index
int mcastTTL = 10;
int loopBack = 1;

if (setsockopt(listener->socket,
IPPROTO_IPV6,
IPV6_MULTICAST_IF,
&interfaceIndex,
sizeof(interfaceIndex))
< 0)
perror("setsockopt:: IPV6_MULTICAST_IF:: ");


if (setsockopt(listener->socket,
IPPROTO_IPV6,
IPV6_MULTICAST_LOOP,
&loopBack,
sizeof(loopBack))
< 0)
perror("setsockopt:: IPV6_MULTICAST_LOOP:: ");


if (setsockopt(listener->socket,
IPPROTO_IPV6,
IPV6_MULTICAST_HOPS,
&mcastTTL,
sizeof(mcastTTL))
< 0)
perror("setsockopt:: IPV6_MULTICAST_HOPS:: ");


struct ipv6_mreq mreq6 = 0;
MEMCOPY(&mreq6.ipv6mr_multiaddr.s6_addr, sourceAddress, 16);
mreq6.ipv6mr_interface = interfaceIndex;

if (setsockopt(listener->socket,
IPPROTO_IPV6,
IPV6_JOIN_GROUP,
&mreq6,
sizeof(mreq6))
< 0)
perror("setsockopt:: IPV6_JOIN_GROUP:: ");



Setting up the socket this way, I can receive ICMP echo requests, replies to my own address, and multicasts sent using the link-local multicast address. However, I don't see any MLDv2 queries.



Here's my receive loop:



 uint8_t received[1000] = 0 ;
struct sockaddr_storage peerAddress = 0 ;
socklen_t addressLength = sizeof(peerAddress);
socklen_t addressLength = sizeof(peerAddress);

int receivedLength = recvfrom(sockfd,
received,
sizeof(received),
0,
(struct sockaddr *)&peerAddress,
&addressLength);

if (receivedLength > 0)
// Never get here for MLDv2 queries.



Researching this a bit further, I discovered the IPV6_ROUTER_ALERT socket option, which the man page describes as follows:



IPV6_ROUTER_ALERT
Pass forwarded packets containing a router alert hop-by-hop option to this socket.
Only allowed for SOCK_RAW sockets. The tapped packets are not forwarded by the
kernel, it is the user's responsibility to send them out again. Argument is a
pointer to an integer. A positive integer indicates a router alert option value
to intercept. Packets carrying a router alert option with a value field
containing this integer will be delivered to the socket. A negative integer
disables delivery of packets with router alert options to this socket.


So I figured I was missing this option, and tried setting it as follows. [RFC2710] 0 means Multicast Listener Discovery message.



 int routerAlertOption = 0;

if (setsockopt(listener->socket,
IPPROTO_IPV6,
IPV6_ROUTER_ALERT,
&routerAlertOption,
sizeof(routerAlertOption))
< 0)
perror("setsockopt:: IPV6_ROUTER_ALERT:: ");



However, this gives me the ENOPROTOOPT error (errno 92). Some more Googling (http://www.atm.tut.fi/list-archive/usagi-users-2005/msg00317.html) led me to the fact that you can't set the IPV6_ROUTER_ALERT option with the IPPROTO_ICMPV6 protocol. It needs a socket defined using the IPPROTO_RAW protocol.



However, defining my socket as:



int fd = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);


means I'm not able to receive any ICMP packets in my recvfrom anymore.




TL;DR: How do I read MLDv2 queries using an IPv6 socket?




edit (answer):
It appears conventional implementations of Linux will drop MLDv2 packets when passing them to an ICMPV6 socket. Why this is, I'm not sure. (Could be because of the next-header option.)



I went with an approach of reading raw packets on the tun0 interface. I followed the ping6_ll.c example here: http://www.pdbuchan.com/rawsock/rawsock.html.



It uses a socket with (SOCK_RAW, ETH_P_ALL). You can also set some SOL_PACKET options to filter on specific multicast rules on your interface.







share|improve this question


























    up vote
    1
    down vote

    favorite












    I have mrd6 installed on my raspberry pi. It registers with a local interface (tun0) and periodically transmits MLDv2 queries over it.



    According to [RFC3810], MLDv2 message types are a subset of ICMPv6 messages, and are identified in IPv6 packets by a preceding Next Header value of 58 (0x3a). They are sent with a link-local IPv6 Source Address, an IPv6 Hop Limit of 1, and an IPv6 Router Alert option [RFC2711] in a Hop-by-Hop Options header.



    I can confirm that I'm seeing these packets periodically over tun0:



    pi@machine:~ $ sudo tcpdump -i tun0 ip6 -vv -XX

    01:22:52.125915 IP6 (flowlabel 0x71df6, hlim 1, next-header Options (0)
    payload length: 36)
    fe80::69bf:be2d:e087:9921 > ip6-allnodes: HBH (rtalert: 0x0000) (padn)
    [icmp6 sum ok] ICMP6, multicast listener query v2 [max resp delay=10000]
    [gaddr :: robustness=2 qqi=125]
    0x0000: 6007 1df6 0024 0001 fe80 0000 0000 0000 `....$..........
    0x0010: 69bf be2d e087 9921 ff02 0000 0000 0000 i..-...!........
    0x0020: 0000 0000 0000 0001 3a00 0502 0000 0100 ........:.......
    0x0030: 8200 b500 2710 0000 0000 0000 0000 0000 ....'...........
    0x0040: 0000 0000 0000 0000 027d 0000 .........}..


    I have a socket set up in my application on tun0 as follows, since I expect these to be ICMP packets:



    int fd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); // ICMP

    // ... bind this socket to tun0

    int interfaceIndex = // tun0 interface Index
    int mcastTTL = 10;
    int loopBack = 1;

    if (setsockopt(listener->socket,
    IPPROTO_IPV6,
    IPV6_MULTICAST_IF,
    &interfaceIndex,
    sizeof(interfaceIndex))
    < 0)
    perror("setsockopt:: IPV6_MULTICAST_IF:: ");


    if (setsockopt(listener->socket,
    IPPROTO_IPV6,
    IPV6_MULTICAST_LOOP,
    &loopBack,
    sizeof(loopBack))
    < 0)
    perror("setsockopt:: IPV6_MULTICAST_LOOP:: ");


    if (setsockopt(listener->socket,
    IPPROTO_IPV6,
    IPV6_MULTICAST_HOPS,
    &mcastTTL,
    sizeof(mcastTTL))
    < 0)
    perror("setsockopt:: IPV6_MULTICAST_HOPS:: ");


    struct ipv6_mreq mreq6 = 0;
    MEMCOPY(&mreq6.ipv6mr_multiaddr.s6_addr, sourceAddress, 16);
    mreq6.ipv6mr_interface = interfaceIndex;

    if (setsockopt(listener->socket,
    IPPROTO_IPV6,
    IPV6_JOIN_GROUP,
    &mreq6,
    sizeof(mreq6))
    < 0)
    perror("setsockopt:: IPV6_JOIN_GROUP:: ");



    Setting up the socket this way, I can receive ICMP echo requests, replies to my own address, and multicasts sent using the link-local multicast address. However, I don't see any MLDv2 queries.



    Here's my receive loop:



     uint8_t received[1000] = 0 ;
    struct sockaddr_storage peerAddress = 0 ;
    socklen_t addressLength = sizeof(peerAddress);
    socklen_t addressLength = sizeof(peerAddress);

    int receivedLength = recvfrom(sockfd,
    received,
    sizeof(received),
    0,
    (struct sockaddr *)&peerAddress,
    &addressLength);

    if (receivedLength > 0)
    // Never get here for MLDv2 queries.



    Researching this a bit further, I discovered the IPV6_ROUTER_ALERT socket option, which the man page describes as follows:



    IPV6_ROUTER_ALERT
    Pass forwarded packets containing a router alert hop-by-hop option to this socket.
    Only allowed for SOCK_RAW sockets. The tapped packets are not forwarded by the
    kernel, it is the user's responsibility to send them out again. Argument is a
    pointer to an integer. A positive integer indicates a router alert option value
    to intercept. Packets carrying a router alert option with a value field
    containing this integer will be delivered to the socket. A negative integer
    disables delivery of packets with router alert options to this socket.


    So I figured I was missing this option, and tried setting it as follows. [RFC2710] 0 means Multicast Listener Discovery message.



     int routerAlertOption = 0;

    if (setsockopt(listener->socket,
    IPPROTO_IPV6,
    IPV6_ROUTER_ALERT,
    &routerAlertOption,
    sizeof(routerAlertOption))
    < 0)
    perror("setsockopt:: IPV6_ROUTER_ALERT:: ");



    However, this gives me the ENOPROTOOPT error (errno 92). Some more Googling (http://www.atm.tut.fi/list-archive/usagi-users-2005/msg00317.html) led me to the fact that you can't set the IPV6_ROUTER_ALERT option with the IPPROTO_ICMPV6 protocol. It needs a socket defined using the IPPROTO_RAW protocol.



    However, defining my socket as:



    int fd = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);


    means I'm not able to receive any ICMP packets in my recvfrom anymore.




    TL;DR: How do I read MLDv2 queries using an IPv6 socket?




    edit (answer):
    It appears conventional implementations of Linux will drop MLDv2 packets when passing them to an ICMPV6 socket. Why this is, I'm not sure. (Could be because of the next-header option.)



    I went with an approach of reading raw packets on the tun0 interface. I followed the ping6_ll.c example here: http://www.pdbuchan.com/rawsock/rawsock.html.



    It uses a socket with (SOCK_RAW, ETH_P_ALL). You can also set some SOL_PACKET options to filter on specific multicast rules on your interface.







    share|improve this question
























      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I have mrd6 installed on my raspberry pi. It registers with a local interface (tun0) and periodically transmits MLDv2 queries over it.



      According to [RFC3810], MLDv2 message types are a subset of ICMPv6 messages, and are identified in IPv6 packets by a preceding Next Header value of 58 (0x3a). They are sent with a link-local IPv6 Source Address, an IPv6 Hop Limit of 1, and an IPv6 Router Alert option [RFC2711] in a Hop-by-Hop Options header.



      I can confirm that I'm seeing these packets periodically over tun0:



      pi@machine:~ $ sudo tcpdump -i tun0 ip6 -vv -XX

      01:22:52.125915 IP6 (flowlabel 0x71df6, hlim 1, next-header Options (0)
      payload length: 36)
      fe80::69bf:be2d:e087:9921 > ip6-allnodes: HBH (rtalert: 0x0000) (padn)
      [icmp6 sum ok] ICMP6, multicast listener query v2 [max resp delay=10000]
      [gaddr :: robustness=2 qqi=125]
      0x0000: 6007 1df6 0024 0001 fe80 0000 0000 0000 `....$..........
      0x0010: 69bf be2d e087 9921 ff02 0000 0000 0000 i..-...!........
      0x0020: 0000 0000 0000 0001 3a00 0502 0000 0100 ........:.......
      0x0030: 8200 b500 2710 0000 0000 0000 0000 0000 ....'...........
      0x0040: 0000 0000 0000 0000 027d 0000 .........}..


      I have a socket set up in my application on tun0 as follows, since I expect these to be ICMP packets:



      int fd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); // ICMP

      // ... bind this socket to tun0

      int interfaceIndex = // tun0 interface Index
      int mcastTTL = 10;
      int loopBack = 1;

      if (setsockopt(listener->socket,
      IPPROTO_IPV6,
      IPV6_MULTICAST_IF,
      &interfaceIndex,
      sizeof(interfaceIndex))
      < 0)
      perror("setsockopt:: IPV6_MULTICAST_IF:: ");


      if (setsockopt(listener->socket,
      IPPROTO_IPV6,
      IPV6_MULTICAST_LOOP,
      &loopBack,
      sizeof(loopBack))
      < 0)
      perror("setsockopt:: IPV6_MULTICAST_LOOP:: ");


      if (setsockopt(listener->socket,
      IPPROTO_IPV6,
      IPV6_MULTICAST_HOPS,
      &mcastTTL,
      sizeof(mcastTTL))
      < 0)
      perror("setsockopt:: IPV6_MULTICAST_HOPS:: ");


      struct ipv6_mreq mreq6 = 0;
      MEMCOPY(&mreq6.ipv6mr_multiaddr.s6_addr, sourceAddress, 16);
      mreq6.ipv6mr_interface = interfaceIndex;

      if (setsockopt(listener->socket,
      IPPROTO_IPV6,
      IPV6_JOIN_GROUP,
      &mreq6,
      sizeof(mreq6))
      < 0)
      perror("setsockopt:: IPV6_JOIN_GROUP:: ");



      Setting up the socket this way, I can receive ICMP echo requests, replies to my own address, and multicasts sent using the link-local multicast address. However, I don't see any MLDv2 queries.



      Here's my receive loop:



       uint8_t received[1000] = 0 ;
      struct sockaddr_storage peerAddress = 0 ;
      socklen_t addressLength = sizeof(peerAddress);
      socklen_t addressLength = sizeof(peerAddress);

      int receivedLength = recvfrom(sockfd,
      received,
      sizeof(received),
      0,
      (struct sockaddr *)&peerAddress,
      &addressLength);

      if (receivedLength > 0)
      // Never get here for MLDv2 queries.



      Researching this a bit further, I discovered the IPV6_ROUTER_ALERT socket option, which the man page describes as follows:



      IPV6_ROUTER_ALERT
      Pass forwarded packets containing a router alert hop-by-hop option to this socket.
      Only allowed for SOCK_RAW sockets. The tapped packets are not forwarded by the
      kernel, it is the user's responsibility to send them out again. Argument is a
      pointer to an integer. A positive integer indicates a router alert option value
      to intercept. Packets carrying a router alert option with a value field
      containing this integer will be delivered to the socket. A negative integer
      disables delivery of packets with router alert options to this socket.


      So I figured I was missing this option, and tried setting it as follows. [RFC2710] 0 means Multicast Listener Discovery message.



       int routerAlertOption = 0;

      if (setsockopt(listener->socket,
      IPPROTO_IPV6,
      IPV6_ROUTER_ALERT,
      &routerAlertOption,
      sizeof(routerAlertOption))
      < 0)
      perror("setsockopt:: IPV6_ROUTER_ALERT:: ");



      However, this gives me the ENOPROTOOPT error (errno 92). Some more Googling (http://www.atm.tut.fi/list-archive/usagi-users-2005/msg00317.html) led me to the fact that you can't set the IPV6_ROUTER_ALERT option with the IPPROTO_ICMPV6 protocol. It needs a socket defined using the IPPROTO_RAW protocol.



      However, defining my socket as:



      int fd = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);


      means I'm not able to receive any ICMP packets in my recvfrom anymore.




      TL;DR: How do I read MLDv2 queries using an IPv6 socket?




      edit (answer):
      It appears conventional implementations of Linux will drop MLDv2 packets when passing them to an ICMPV6 socket. Why this is, I'm not sure. (Could be because of the next-header option.)



      I went with an approach of reading raw packets on the tun0 interface. I followed the ping6_ll.c example here: http://www.pdbuchan.com/rawsock/rawsock.html.



      It uses a socket with (SOCK_RAW, ETH_P_ALL). You can also set some SOL_PACKET options to filter on specific multicast rules on your interface.







      share|improve this question














      I have mrd6 installed on my raspberry pi. It registers with a local interface (tun0) and periodically transmits MLDv2 queries over it.



      According to [RFC3810], MLDv2 message types are a subset of ICMPv6 messages, and are identified in IPv6 packets by a preceding Next Header value of 58 (0x3a). They are sent with a link-local IPv6 Source Address, an IPv6 Hop Limit of 1, and an IPv6 Router Alert option [RFC2711] in a Hop-by-Hop Options header.



      I can confirm that I'm seeing these packets periodically over tun0:



      pi@machine:~ $ sudo tcpdump -i tun0 ip6 -vv -XX

      01:22:52.125915 IP6 (flowlabel 0x71df6, hlim 1, next-header Options (0)
      payload length: 36)
      fe80::69bf:be2d:e087:9921 > ip6-allnodes: HBH (rtalert: 0x0000) (padn)
      [icmp6 sum ok] ICMP6, multicast listener query v2 [max resp delay=10000]
      [gaddr :: robustness=2 qqi=125]
      0x0000: 6007 1df6 0024 0001 fe80 0000 0000 0000 `....$..........
      0x0010: 69bf be2d e087 9921 ff02 0000 0000 0000 i..-...!........
      0x0020: 0000 0000 0000 0001 3a00 0502 0000 0100 ........:.......
      0x0030: 8200 b500 2710 0000 0000 0000 0000 0000 ....'...........
      0x0040: 0000 0000 0000 0000 027d 0000 .........}..


      I have a socket set up in my application on tun0 as follows, since I expect these to be ICMP packets:



      int fd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); // ICMP

      // ... bind this socket to tun0

      int interfaceIndex = // tun0 interface Index
      int mcastTTL = 10;
      int loopBack = 1;

      if (setsockopt(listener->socket,
      IPPROTO_IPV6,
      IPV6_MULTICAST_IF,
      &interfaceIndex,
      sizeof(interfaceIndex))
      < 0)
      perror("setsockopt:: IPV6_MULTICAST_IF:: ");


      if (setsockopt(listener->socket,
      IPPROTO_IPV6,
      IPV6_MULTICAST_LOOP,
      &loopBack,
      sizeof(loopBack))
      < 0)
      perror("setsockopt:: IPV6_MULTICAST_LOOP:: ");


      if (setsockopt(listener->socket,
      IPPROTO_IPV6,
      IPV6_MULTICAST_HOPS,
      &mcastTTL,
      sizeof(mcastTTL))
      < 0)
      perror("setsockopt:: IPV6_MULTICAST_HOPS:: ");


      struct ipv6_mreq mreq6 = 0;
      MEMCOPY(&mreq6.ipv6mr_multiaddr.s6_addr, sourceAddress, 16);
      mreq6.ipv6mr_interface = interfaceIndex;

      if (setsockopt(listener->socket,
      IPPROTO_IPV6,
      IPV6_JOIN_GROUP,
      &mreq6,
      sizeof(mreq6))
      < 0)
      perror("setsockopt:: IPV6_JOIN_GROUP:: ");



      Setting up the socket this way, I can receive ICMP echo requests, replies to my own address, and multicasts sent using the link-local multicast address. However, I don't see any MLDv2 queries.



      Here's my receive loop:



       uint8_t received[1000] = 0 ;
      struct sockaddr_storage peerAddress = 0 ;
      socklen_t addressLength = sizeof(peerAddress);
      socklen_t addressLength = sizeof(peerAddress);

      int receivedLength = recvfrom(sockfd,
      received,
      sizeof(received),
      0,
      (struct sockaddr *)&peerAddress,
      &addressLength);

      if (receivedLength > 0)
      // Never get here for MLDv2 queries.



      Researching this a bit further, I discovered the IPV6_ROUTER_ALERT socket option, which the man page describes as follows:



      IPV6_ROUTER_ALERT
      Pass forwarded packets containing a router alert hop-by-hop option to this socket.
      Only allowed for SOCK_RAW sockets. The tapped packets are not forwarded by the
      kernel, it is the user's responsibility to send them out again. Argument is a
      pointer to an integer. A positive integer indicates a router alert option value
      to intercept. Packets carrying a router alert option with a value field
      containing this integer will be delivered to the socket. A negative integer
      disables delivery of packets with router alert options to this socket.


      So I figured I was missing this option, and tried setting it as follows. [RFC2710] 0 means Multicast Listener Discovery message.



       int routerAlertOption = 0;

      if (setsockopt(listener->socket,
      IPPROTO_IPV6,
      IPV6_ROUTER_ALERT,
      &routerAlertOption,
      sizeof(routerAlertOption))
      < 0)
      perror("setsockopt:: IPV6_ROUTER_ALERT:: ");



      However, this gives me the ENOPROTOOPT error (errno 92). Some more Googling (http://www.atm.tut.fi/list-archive/usagi-users-2005/msg00317.html) led me to the fact that you can't set the IPV6_ROUTER_ALERT option with the IPPROTO_ICMPV6 protocol. It needs a socket defined using the IPPROTO_RAW protocol.



      However, defining my socket as:



      int fd = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);


      means I'm not able to receive any ICMP packets in my recvfrom anymore.




      TL;DR: How do I read MLDv2 queries using an IPv6 socket?




      edit (answer):
      It appears conventional implementations of Linux will drop MLDv2 packets when passing them to an ICMPV6 socket. Why this is, I'm not sure. (Could be because of the next-header option.)



      I went with an approach of reading raw packets on the tun0 interface. I followed the ping6_ll.c example here: http://www.pdbuchan.com/rawsock/rawsock.html.



      It uses a socket with (SOCK_RAW, ETH_P_ALL). You can also set some SOL_PACKET options to filter on specific multicast rules on your interface.









      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 13 '17 at 2:52

























      asked Nov 10 '17 at 14:34









      Suvesh Pratapa

      1063




      1063

























          active

          oldest

          votes











          Your Answer







          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "106"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f403765%2freading-mldv2-queries-using-an-ipv6-socket%23new-answer', 'question_page');

          );

          Post as a guest



































          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes















           

          draft saved


          draft discarded















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f403765%2freading-mldv2-queries-using-an-ipv6-socket%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          How to check contact read email or not when send email to Individual?

          Bahrain

          Postfix configuration issue with fips on centos 7; mailgun relay