¿Cómo permite macOS que los usuarios estándar hagan ping?

Tengo una pregunta bastante profunda aquí que espero que alguien pueda responder. En macOS, los usuarios normales pueden hacer ping y rootear. Normalmente, se requiere acceso de root para abrir el socket sin formato necesario para ejecutar ping. He notado que en Linux esto generalmente se logra agregando atributos extendidos al archivo del programa ping para permitir el acceso a nivel de raíz para abrir sockets sin procesar (en el pasado, esto se hacía simplemente configurando el bit setuid en el programa ping, permitiéndole hacer cualquier cosa en su programación como root).

Miré /sbin/ping en macOS (High Sierra, específicamente), y no se establecieron tales atributos, y tampoco setuid. Entonces, ¿qué está haciendo macOS para permitir que los usuarios estándar (no root) hagan ping? ¿Están enviando paquetes ICMP a través de TCP o UDP? Si es así (o si hay otro mecanismo que me falta por completo), ¿puede indicarme algunos documentos? Cualquier ayuda sería apreciada.

¡ICMP está un nivel por debajo de la capa de transporte (TCP, UDP...)!
¿Podría documentar "normalmente, se requiere acceso de root para abrir el socket sin formato". Esto parece ser simplemente que macOS no cumple con sus expectativas y me gustaría evitar cerrar esto como poco claro/buscar referencias fuera del sitio. Sencillamente, el modelo de seguridad no requiere las prohibiciones que eligió Linux.
¿Está preguntando cómo hacer ping como usuario estándar o cómo Apple permite que los usuarios estándar hagan ping? Solo por un poco de claridad.
@bmike: no estoy seguro de lo que quiere decir con "buscar referencias fuera del sitio". No he visto una regla en Stack Exchange que prohíba o desaliente la vinculación a otros sitios. Por el contrario, esa es una práctica común y útil. Tal vez estoy malinterpretando su declaración, así que si tiene un enlace (en el sitio) que explica esa y otras reglas que necesito saber, se lo agradecería.

Respuestas (1)

Echemos un vistazo al código fuente de la implementación de Apple ping. En particular, vemos esto:

if (getuid())
    s = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
else
    s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
sockerrno = errno;

getuiddevuelve 0 si es root. Entonces, este código dice: "abra el socket en DGRAM (modo de datagrama) si no somos root. Si somos root, abra como sin procesar".

Entonces, un socket sin formato solo se usa cuando eres root. Un paquete de ping IMCP es un paquete DGRAM estándar y no requiere conectores sin formato.

Sin embargo, hay algunas banderas que se pueden pasar pingque requieren root, y para ellas obtendrá una "Operación no permitida". Por ejemplo:

>ping -f
ping: -f flag: Operation not permitted

Cuando ejecuto como root, no obtengo la operación no permitida. Entonces, la implementación de Apple le permitirá realizar operaciones de ping estándar que no requieren root, pero requieren que se ejecute como root para ciertas banderas y operaciones.

Dependiendo de si es root, puede establecer algunas opciones de socket adicionales:

if (uid == 0)
    (void)setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&hold,
        sizeof(hold));
No tenía idea de que Apple había lanzado ese código fuente. ¡Fantástico! Y eso responde a mi pregunta, muchas gracias.