7

I was learning the Linux ping command and its options, and read about the -m option which is used to mark the outgoing packet. When receiving, we can filter that marked packet result first.

I am trying to set the mark for the packet, but I got a warning message:

$ ping -m 10 server
PING server (192.168.2.2) 56(84) bytes of data.
Warning: Failed to set mark 10
64 bytes from server (192.168.2.2): icmp_req=1 ttl=64 time=0.182 ms
64 bytes from server (192.168.2.2): icmp_req=2 ttl=64 time=0.201 ms

So, why does it fail to mark? How can I mark a packet using the -m option?

terdon
  • 242,166

1 Answers1

17

Short answer: You can't do with a normal user.

Long answer: To be able to mark packets, you need to be a root user, or at least a user with the SO_MARK capability(needs to be set as root):

SO_MARK at socket(7):

   SO_MARK (since Linux 2.6.25)
          Set the mark for each packet sent through this socket (similar
          to the netfilter MARK target but socket-based).  Changing the
          mark can be used for mark-based routing without netfilter or
          for packet filtering.  Setting this option requires the
          CAP_NET_ADMIN capability.

The piece of code at ping_common.c from iputils that confirms this theory:

#ifdef SO_MARK
if (options & F_MARK) {
    int ret;

    enable_capability_admin();
    ret = setsockopt(sock->fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark));
    disable_capability_admin();

    if (ret == -1) {
        /* we probably dont wanna exit since old kernels
         * dont support mark ..
        */
        fprintf(stderr, "Warning: Failed to set mark %d\n", mark);
    }
}
#endif

To learn more about capabilities: man capabilities(7) and capabilities(7) overview.

If you want to go further on capabilities with all other binaries of the system, this is a good way to probe them. Involves kernel compilation so, it could not be suitable for production environment.

ICMP marking usefulness:

As it is described on manpages:

-m mark     
    use mark to tag the packets going out. This is useful for variety of reasons
    within the kernel such as using policy routing to select specific outbound processing.

And as explained on a superuser question, this feature could be useful when probing multilink/multiroute network environment, where you need to force that an ICMP packet goes through one specific "flow".

Practical example. Host 1:

$ ping -m 10 <host>

Host 2. Alter the default policy of INPUT to DROP and accept packets only from the source ip of the specific route that has the mark 10 on host 1:

# iptables -P INPUT DROP
# iptables -A INPUT -s <IP_SOURCE_MARK_10> -p icmp -j ACCEPT

This was already explained here. Again, it will be better used for routing decisions debugging(if you have more than one path between 2 hosts), since a tcpdump -nevvv -i <interface> src host <source_host> will be more than enough to just probe "icmp packet arrival".

  • Why it is restricted for root user only ? –  May 04 '16 at 11:23
  • 1
    Because it involves packet marking, thus, socket manipulation. It's a vector for possible attacks that could exploit anything related to network stack and maybe the kernel. That's why you don't have permissions to "ping mark" on most distros as default, and you should not allow unless you need it for some special reason. –  May 04 '16 at 11:28
  • when it is useful? –  May 04 '16 at 11:30
  • When you need to ping one server to another and you need to "agree" on a special mark for debug. Another application could be multilink debug, where you mark your links and you need to send icmp through one specific vlan/interface/adsl_link. –  May 04 '16 at 11:31
  • I am not able to understand. Please give me little bit more information ? –  May 04 '16 at 11:33
  • @suresh, i have improved my answer to reflect your needs. Please, take your time to read it and feel free comment if you still have doubts :) –  May 04 '16 at 11:51
  • @nwildner Can you reexamine the last part of your answer which is saying that you can mark a packet on one machine and use the mark in an iptables rule on another machine? There is another question about this, and based on what is being posted there it's not possible to transmit a mark from one host to another. – David Z May 23 '16 at 11:58