# Implementaciones de TCP

Existen varias implementaciones del protocolo TCP, cada una con sus ventajas e inconvenientes. Para evitar la repetición de trabajo es común que unas se basen en otras, lo que lleva a que también compartan los mismos fallos.

## Historia

Las primeras implementaciones surgieron en los años 1980 por parte de los sistemas BSD, que derivaban de los UNIX. En esta época aún se estaba desarrollando la historia de Internet.
4.1aBSD, publicada en junio de 1981, ya tenía una versión preliminar de TCP/IP, basada en el trabajo de Bolt, Beranek y Newman (BBN) pero algo modificada. La versión 4.1cBSD (1982) tuvo una implementación mejor, y se incluyó en 4.2BSD (1983), que fue la primera que se distribuyó a gran escala. DARPA decidió que sería esta versión la que se quedaría en 4.3BSD (junio de 1986); además, en esta versión se mejoró su rendimiento.
De 4.3BSD deriva 4.3BSD-Tahoe (junio de 1988), y de ésta 4.3BSD-Reno (1990), en el camino para la creación de 4.4BSD (1993). Los nombres Tahoe y Reno son los que identificarán a las implementaciones TCP de estos sistemas. Corresponden a ciudades del estado de Nevada (Estados Unidos) famosas por sus casinos: Tahoe, Reno (Nevada); también Las Vegas sirve como nombre a otra versión de 1994.
Un listado del nivel de implementación de TCP en cada una de estas versiones es:
* 1983: 4.2BSD: primera versión ampliamente disponible de TCP/IP
* 1986: 4.3BSD: mejor rendimiento de TCP
* 1988: 4.3BSD-Tahoe: inicio lento ("slow-start"), control de congestión ("congestion avoidance"), retransmisión rápida ("fast retransmit")
* 1990: 4.3BSD-Reno: recuperación rápida ("fast recovery"), predicción de cabeceras TCP, cabecera SLIP, compresión
* 1993: 4.4BSD: multidifusión, modificaciones para canales de alto rendimiento (RFC 1323)
* 1994: 4.4BSD-Lite
Existe poca documentación técnica que recoja los cambios entre versiones. En los libros de Karels y McKusick de 1986
se describen los cambios de 4.2BSD a 4.3BSD, y Jacobson describe en 1990 los cambios de 4.3BSD-Tahoe a 4.3BSD-Reno. (, pág. 5)

## Implementaciones base

Durante el inicio de TCP hubo tres implementaciones base:
* Tahoe, la de 4.3BSD-Tahoe, derivado de 4.3BSD
* Reno, la de 4.3BSD-Reno, derivada de Tahoe, y usada después en 4.4BSD-Lite
* Vegas, que mejora a Reno en velocidad entre un 40 y 70% (según página de Vegas, de 1994)
Es especialmente importante la implementación de TCP de 4.4BSD-Lite, que salió en junio de 1994, y es la que se toma como referencia por haber sido la base de muchos sistemas actuales. Hoy en día, se sigue usando para enseñar cómo funciona un sistema TCP.
Muchas implementaciones actuales se han basado en alguna de estas tres en algún momento. Sin embargo, si hoy se creara una nueva, probablemente se basaría en una de las modernas (como la de FreeBSD, OpenBSD, NetBSD o BSD/OS) antes que en la original de 4.4BSD-Lite.
La reutilización del código de BSD fue posible debido a su licencia (licencia BSD), que permite que sea usado en otros sistemas, tanto software libre como propietario. Por ejemplo, Microsoft Windows usa código derivado de BSD en su implementación de TCP, e incluye herramientas de red para consola originales de BSD (detalles). También Darwin BSD, el sistema base de Mac OS X, parcialmente deriva de FreeBSD 5. Otros UNIX comerciales, como Solaris, también incluyen código BSD.

### Derivadas

Se han hecho varias versiones que mejoran a Tahoe, Reno y Vegas. Por ejemplo, según, las más populares son:
* Tahoe sin "Fast Retransmit": incluye inicio lento y control de congestión
* Tahoe: incluye también retransmisión rápida
* Reno: añade recuperación rápida a Tahoe
* New-Reno: versión de Reno con un sistema mejorado de recuperación rápida
* Reno Plus: en algunos sistemas Solaris
* SACK: usa confirmaciones (ACK) selectivas
Además de Vegas, Peach, ATCP, y otras (Westwood, Hybla, etc.). En el mismo artículo se describen sus características, y, de entre las 6 de esta lista, se concluye que New-Reno es la implementación más fiable.
Otro estudio sí que tiene en cuenta a Vegas, y concluye que Vegas es mejor que el resto de implementaciones probadas (Tahoe, Reno, New-Reno y SACK).

## Implementaciones según sistema operativo

Cada sistema operativo muestra un comportamiento distinto en cuanto a TCP, pero algunos se parecen entre ellos porque han compartido código (principalmente, el de BSD). A veces se clasifican los sistemas según a qué implementación base se parecen (Tahoe, Reno, New-Reno, Vegas, etc.). Los que usan un código escrito desde cero son los que más se diferencian del resto.

### BSD

El 4.4BSD original (implementación base) permite cuatro familias de protocolos: TCP/IP, Xerox Network Services (XNS), OSI, sockets IPC ("UNIX domain sockets"). En, pág. 9, se explica cómo está organizado el código dentro del kernel, y en el resto del libro se explican las funciones de red.
Otro estudio, modelización, y análisis de rendimiento del BSD original es, que además cita estudios anteriores hechos sobre este código. Se explica también el funcionamiento de implementaciones derivadas, como la de FreeBSD, a la hora de montar un enrutador por software.
FreeBSD, NetBSD y OpenBSD son todos derivados de BSD, y por eso han heredado algunos de sus protocolos de red.

### Linux

El código de TCP en Linux se escribió de forma independiente al resto de implementaciones. Hay que tener en cuenta que, al estar bajo la licencia GPL, no podría haber usado el código de los sistemas BSD, ya que éstos usaban la licencia BSD original (con la cláusula de publicidad), incompatible con la GPL (véase ). Esta cláusula se quitó mucho más tarde, en 1999.
Todos los detalles de implementación de TCP en Linux están visibles y explicados en su código fuente, disponible en . La parte relacionada con TCP en IPv4 está en el directorio net/ipv4/. Aquí se encuentran archivos importantes, como:
* tcp_ipv4.c
* tcp_input.c
* tcp_output.c
En net/ipv6/ está el código para implementar TCP sobre IPv6. Es una adaptación del código para IPv4.
En un sistema en ejecución, varios parámetros de TCP se pueden ver y modificar mediante los archivos del directorio /proc, por ejemplo /proc/sys/net/ipv4/
Existen varios libros que explican los detalles de implementación de TCP/IP en el núcleo Linux y analizan su código. Uno de ellos, que describe hasta la versión 2.4, es:
* Wehrle, Klaus; Pahlke, Frank; Ritter, Hartmut; Muller, Daniel; Bechler, Marc (2004). Linux Network Architecture. Prentice Hall. ISBN 0-13-177720-3.
Linux implementa muchos algoritmos de control de congestión. Por ejemplo, está SACK, Westwood+ (ver artículo explicativo: ), Reno, NewReno, FACK (forward acknowledgement), ECK, H-TCP, y varios más. Desde la versión 2.6.19 se usa por defecto CUBIC con NewReno como salvaguarda.
Se puede cambiar el algoritmo usado por defecto ajustando las opciones de compilación, tal como se ve en la imagen adjunta. Aunque al ser modular, también puede ser cambiado en caliente modificando /proc/sys/net/ipv4/tcp_congestion_control.
Linux 2.4 usando el algoritmo SACK (acuse de recibo selectivo) consigue un rendimiento mayor que otros sistemas que también usan SACK (como OpenBSD y FreeBSD), según
Comparando las implementaciones modernas (2004/2005), se ve que han evolucionado por caminos distintos, pero que todas aguantan bien la congestión de red (a diferencia de la implementación original de BSD). Según las pruebas, Linux 2.6 el que mejor rendimiento da (de entre FreeBSD 5.3, OpenBSD 3.5, y Windows XP Service Pack 2).
Como el desarrollo de Linux es un proceso abierto al público, en Internet se encuentran páginas que explican los problemas que daba su implementación de TCP, y cómo se han solucionado. Por ejemplo: mejora de rendimiento en la versión 2.0.36 (marzo de 1999), problemas de TCP detectados al hacer una comparativa (1999), ajustes para 2.4 y 2.6 Archivado el 18 de octubre de 2007 en Wayback Machine. (febrero de 2006), problemas en los algoritmos de TCP en Linux 2.6.16.3 (junio de 2006), entre otros. Es habitual que estos fallos se detecten cuando alguien está escribiendo un documento técnico o comparativa. En caso de comportamiento extraño, un estudio del código fuente sirve para confirmar las sospechas y poder corregir el error en Linux. Como ejemplo, véanse los siguientes artículos sobre redes inalámbricas:
o sobre BIC-TCP:

### Windows

Según uno de los programadores del código de red de Windows NT/2000:
Microsoft estaba programando en 1990 el sistema de red para Windows NT. El protocolo usado entonces era uno llamado NetBEUI, pero se vio que TCP/IP se volvía cada vez más importante, y por eso se decidió incluirlo en NT. De esta forma, Microsoft se hacía compatible con los UNIX (que usaban TCP/IP desde 1982) a la vez que se posicionaba en contra de Novell Netware, que dominaba el mercado de redes en los años 90 con su protocolo IPX/SPX (incompatible con TCP/IP hasta 1999).
El hecho de incluir TCP/IP en Windows obligó a cambiar la interfaz de acceso a red de NetBEUI (que era NetBIOS) por un sistema de sockets llamado Winsock, basado en el de BSD (los sockets Berkeley).
El propio código de TCP/IP (la pila) se compró a una compañía llamada Spider Systems. Su versión estaba basada (total o parcialmente) en el código de BSD y otros UNIX, ya que la licencia BSD lo permite (sólo requiere dar crédito al autor original). Sin embargo, usaba la interfaz STREAMS, una alternativa a los sockets Berkeley, que servía como capa de abstracción para los componentes de red como TCP e IP.
Esto hacía que la implementación fuera más lenta que si usara TCP/IP directamente, así que Microsoft escribió una pila TCP/IP nueva (quizás basándose en el código anterior), que incluyó en Windows NT y Windows 95. Por eso ambos sistemas muestran el mismo comportamiento en las pruebas (ejemplo:), que además es distinto al de otras implementaciones.
Junto con el código comprado a Spider Systems, se incluían utilidades de red para consola, como los programas para Telnet, FTP, rcp o rsh, sacados directamente de BSD. Éstos no se reescribieron, ya que funcionaban bien y no hay problemas con la licencia. Aún se muestra el copyright original, que es The Regents of the University of California (universidad de la que forma parte Berkeley, que es la B del BSD).
En cuanto a la parte técnica: en
se describen algunos detalles de implementación de TCP/IP en Windows 2000, incluyendo los RFC que cumple, la arquitectura de red, y los parámetros usados en TCP.

### Macintosh

Los primeros ordenadores de Apple Computer usaban la familia de protocolos AppleTalk (ya incluidos en el Apple Macintosh original, en 1984). Con el tiempo, estos protocolos se sustituyeron por la familia TCP/IP.
A partir de la versión 7.5.1 de su sistema (System 7) se usó la implementación MacTCP, hoy considerada obsoleta y con problemas de compatibilidad con los protocolos actuales.
En mayo de 1995, Apple presentó, junto con su Power Mac 9500, la arquitectura Open Transport, que es la que reemplazaría a MacTCP (véase anuncio de 1995). m Se incluyó en la versión 7.5.2 del sistema, pero también se hizo disponible para versiones anteriores. Este entorno estaba basado en una implementación de STREAMS llamada Mentat Portable Streams y comprada a la empresa Mentat (más datos: ).
Open Transport funcionaba más rápido que MacTCP, por lo que tuvo buena acogida entre usuarios y programadores. Al ser un sistema STREAMS, permitía gran flexilidad al aplicar filtros a protocolos. Se incluía código para manejar TCP/IP, AppleTalk y dispositivos serie. Hay una descripción extensa en: .
Sin embargo, más adelante (al llegar Mac OS X) se abandonó el sistema Open Transport -basado en STREAMS- para adoptar los sockets Berkeley, mucho más comunes.
Mac OS X (de 2001) se desarrolló basándose en Darwin BSD, que está basado en FreeBSD 5 y por tanto tiene una implementación derivada de la de 4.4BSD. Existen diferencias entre FreeBSD y la versión Mac OS X (véase lista), pero no en cuanto a la implementación de TCP.

### Listado de versiones de TCP usadas

Aquí se listan varios sistemas operativos junto con el comportamiento TCP que presentan. Los resultados están agrupados según la fuente del estudio.
Según un estudio de 1997:
* BSDI 1.1, 2.0, 2.1a: Reno
* DEC OSF/1 1.3a, 2.0, 3.0, 3.2: Reno
* HP/UX 9.05, 10.00: Reno
* IRIX 4.0, 5.1, 5.2, 5.3, 6.2a: Reno
* Linux 1.0: independiente
* NetBSD 1.0: Reno
* Solaris 2.3, 2.4: independiente
* SunOS 4.1: Tahoe
* Linux 2.0.30, 2.1.36: independiente
* Trumpet/Winsock 2.0b, 3.0c: independiente
* Windows 95, NT: independiente
Según un estudio de 2000:
* FreeBSD 3.5.1, 4.2: Reno
* FreeBSD 4.3, 4.4, 4.5: New-Reno
* Windows 98, 2000: Tahoe sin "Fast Retransmit"
* RedHat 7.2: New-Reno
En
se estudian y describen otras:
* Solaris 2.1
* SunOS 4.0.3, 4.1.1
* HP-UX 9.0
* IRIX 5.1.1

## Otras implementaciones

No sólo se programan algoritmos de TCP para usarse en computadoras. Aquí se listan otros casos en los que se han creado implementaciones de estos protocolos de red.

### Para microcontroladores

Existe código para implementar la pila TCP/IP en microcontroladores de 8 o 16 bits, con menos memoria RAM de la habitual en un computadora personal. En este caso hay restricciones especiales: por ejemplo, el código ha de ocupar pocos kilobytes, y el uso de RAM ha de ser también bajo, todo esto sin dejar de cumplir el estándar (los RFC).
Un ejemplo es uIP. Está escrito en C, es software libre, e implementa ARP, IP, TCP, UDP, ICMP, entre otros. Se usa en sistemas como Contiki, FreeRTOS, TinyOS y xmk.

### Educativas

Se han creado varios sistemas que implementan TCP para ser usados en la enseñanza de sistemas operativos y redes. Uno de los primeros fue Xinu, para ordenadores VAX, PDP-11, y otros, y usado en los años 1980.
Minix es otro sistema operativo para docencia, muy usado, y que contiene una implementación de TCP/IP. En la página Minix Network Service Documentation se puede encontrar un análisis de su sistema de red, aunque se excluye el protocolo TCP.

### Pruebas conceptuales

También hay implementaciones de TCP en lenguajes de alto nivel, sólo para demostrar que es posible (prueba de concepto). No tienen gran utilidad, ya que los sistemas operativos se programan en lenguajes de bajo nivel (como C), pero sí que pueden usarse en sistemas embebidos; por ejemplo, en un microcontrolador que sólo tiene Java.

### Sistemas menores

Algunos sistemas operativos pequeños (no tan importantes como Unix) también tienen su propia implementación de TCP y de otros protocolos. Aparte de los educativos, están:
* BeOS tiene una implementación de TCP que es lenta y tiene algunos problemas (ej.)
* GNU Hurd usa el mismo código TCP/IP que Linux, pero como un demonio en espacio de usuario. (Código)
* KA9Q, sistema de paquetes por radio para MS-DOS
* Plan 9 from Bell Labs, basado en ideas de Unix pero con una nueva implementación de TCP/IP (tcp.c de Plan9)
* QNX usa una interfaz de red basada en BSD
* Syllable, con una implementación nativa
* wattcp, para MS-DOS

### Implementaciones en hardware

Normalmente el protocolo TCP es usado por el sistema operativo, (que forma parte del software), mientras que la tarjeta de red (que es hardware) se encarga del protocolo Ethernet o similares. Pero además existen chips de TCP, o sea, circuitos integrados capaces de encargarse también de este protocolo, de forma que todo el control de las conexiones ya no tiene que hacerlo la unidad central de procesamiento.
A este tipo de tarjetas de red se les llama TOE (por TCP Offload Engine). Existe una patente que cubre todos estos aceleradores de red en Estados Unidos: patente 20040042487.
Un sistema TOE puede mejorar el rendimiento en algunos casos, ya que el hardware libera a la CPU de trabajos intensos, como:
* Establecimiento de la conexión
* Acuse de recibo de cada paquete
* Verificación de cada paquete
* Números de secuencia
* Cálculo de la ventana deslizante
* Fin de la conexión
Sin embargo, el sistema TOE tiene puntos en contra, que hacen que algunos fabricantes no lo soporten (por ejemplo, Linux; véase ). Como desventajas de TOE se citan:
* Ya que el firmware de una tarjeta de red suele ser código cerrado, se depende del fabricante original para que arregle los fallos que se encuentren, y para ofrecer el soporte técnico a los usuarios.
* Cada TOE implica una nueva implementación de TCP, diferente al resto en cuanto a comportamiento, posiblemente poco fiel a los RFC, y que necesitaría actualizar las herramientas de análisis de red.
* La solución por hardware TOE puede ser más eficiente al principio, pero queda anticuada fácilmente cuando el resto de hardware del ordenador evoluciona (mucho más rápido).
* Se ha visto que para algunas tareas el rendimiento es menor, ya que hay que hacer trabajo extra para programar el hardware.
* El hardware de una tarjeta de red está más limitado que el resto de recursos de los que dispone un ordenador.
* Es fácil aprovechar los límites de un TOE para hacer un ataque de denegación de servicio.
* Un sistema TOE está poco integrado con el sistema operativo, e impide que el sistema tenga una visión global de las conexiones.

## Detalles técnicos

Cada implementación es el resultado de varias decisiones de diseño; por ejemplo:
* Interfaz (API) usada por los programas. Son muy usados los sockets, en concreto los sockets Berkeley (desde 4.2BSD), pero hay otros sistemas, como Transport Layer Interface (TLI).
* Funciones de red. Pueden estar como llamada al sistema o como funciones dentro de una biblioteca. ( pág. 8).
* Estructuras de datos usadas, descriptores, búfers, etc.
* Tratamiento de las interrupciones y prioridades.
* Pasos exactos para el inicio y terminación de una conexión.
* Dónde se guarda el estado de cada conexión.
* Aleatoriedad de los números de secuencia.

## Problemas posibles

Las versiones de TCP evolucionan constantemente, por lo que se deduce que existen muchos fallos corregidos y por corregir.
La Internet Society publicó en 1999, en el RFC 2525, una lista de problemas detectados en las implementaciones TCP del momento. Los clasificó en control de congestión, rendimiento, fiabilidad y control de recursos. El objetivo era que los servidores perdieran menos tiempo procesando tanto conexiones erróneas como datos transferidos, para así asegurar la estabilidad de Internet.
Otra clasificación posible es en:
* Problemas de seguridad: los que permiten a un atacante hacer algo que no estaba previsto.
* Problemas de rendimiento: lentitud cuando hay congestión de red o en otros casos especiales.
* Problemas de interoperabilidad: los provocados entre versiones que no cumplen igual de bien el estándar.
Naturalmente, estas clasificaciones no son exclusivas, ya que, por ejemplo, un problema de interoperabilidad puede provocar un mal rendimiento, y esto además puede considerarse un problema de seguridad.

### Problemas de seguridad

La mayoría de implementaciones han tenido errores que permiten atacar a un sistema mediante un ataque de denegación de servicio. Otros fallos pueden también facilitar el IP spoofing (alguien se mete dentro de otra conexión). Si se habla de la familia completa TCP/IP, las vulnerabilidades pueden ser muchas.
Además de los problemas encontrados en implementaciones concretas, ha habido errores del propio protocolo TCP tal como se definió en el RFC 793 (el original):
* Posible denegación de servicio, sobre todo en BGP. 20 de abril de 2004. NISC 236929. Detalles específicos para NetBSD: . Hay además una discusión extensa sobre la vulnerabilidad, y artículos que explican que las consecuencias de este fallo son poco graves.
* Posible DoS usando los paquetes ACK. 10 de noviembre de 2005. VU#102014.
Véase también el artículo de 1989 sobre problemas de seguridad en la familia de protocolos TCP/IP , más genérico, pero que ya incluye la predicción de números de secuencia entre los problemas de TCP.
Como TCP no fue diseñado para ser seguro (los datos viajan sin cifrar, se puede falsear la identidad, etc.) hay varios intentos para corregirlo; por ejemplo: T/TCP (TCP para transacciones) y Secure TCP.

### Problemas de rendimiento

Este tipo de problemas es el más común, ya que casi siempre es posible mejorar el rendimiento de los algoritmos. Con cada nueva versión de una implementación de TCP se suelen incluir correcciones de este tipo, así que basta con mirar el historial de cambios para tener ejemplos. Los RFC también informan sobre problemas de rendimiento encontrados en TCP y otros protocolos, además de ideas para solucionarlos.
Lo que se intenta conseguir es más velocidad de transferencia de datos incluso en condiciones de congestión de red. Para ello, se puede intentar reducir el número de conexiones perdidas, o el tiempo de CPU usado para procesar cada conexión correcta, entre otras cosas.
Hay muchos estudios técnicos relacionados con este tema, además de comparativas de rendimiento entre distintas implementaciones.

### Problemas de interoperabilidad

No todos los implementadores cumplen completamente el estándar (los RFC), y, en las secciones donde éste es poco preciso, es habitual que lo implementen de formas distintas. Esto crea muchos comportamientos distintos en Internet, y algunos de ellos pueden causar problemas menores (por ejemplo, tener que repetir una conexión).
El RFC 1122 explica los requisitos que ha de cumplir una implementación TCP, a nivel de la capa de comunicación. Le complementan el RFC 1123, que dice cómo han de comportarse las aplicaciones, y el RFC 1127, que habla de las técnicas que debe permitir el sistema operativo para que pueda funcionar bien en Internet.
El RFC 1122, igual que otros RFC, incluye palabras como "MUST", "SHOULD" y "MAY" para decir qué partes son obligatorias implementar y cuáles no. Después divide las implementaciones en tres tipos:
* no cumplidora [del estándar] si no satisface uno o más de los requisitos "MUST"
* incondicionalmente cumplidora si satisface todos los "MUST" y todos los "SHOULD"
* condicionalmente cumplidora si satisface todos los "MUST" pero no todos los "SHOULD"
Como ejemplo de situación en la que varias implementaciones se comportan de forma distinta, está el caso de cerrar una conexión, por ejemplo al acabar de pedir una página web por protocolo HTTP. Algunos sistemas usan un paquete FIN del cliente, seguido por un FIN+ACK del servidor, y un ACK del cliente. Otros cierran la conexión a base de paquetes RST.
Hay más ejemplos de desviaciones del estándar en manuales sobre identificación de sistemas (ej:
), ya que estos comportamientos distintos se pueden usar para adivinar qué implementación está usando un ordenador.

## Verificación y pruebas

Ya que una mala implementación de TCP puede causar congestiones, se dedica mucho esfuerzo a estudiar los problemas de las implementaciones existentes. Algunos de los parámetros que se evalúan son:
* Corrección funcional: cómo de estrictamente cumple con el estándar TCP
* Rendimiento: cómo de rápido permite enviar datos
* Comportamiento en caso de estrés: qué es lo que pasa cuando hay mucha carga
El IETF explica en el RFC 2398 algunas herramientas que se pueden usar para comprobar una implementación de TCP. Se incluyen programas como simuladores de red, servidores, bibliotecas, y modificaciones al núcleo de algunos sistemas UNIX.
Uno de los métodos disponibles para hacer estas pruebas es tratar a la implementación como una caja negra y estudiarla desde fuera, de forma activa: primero se ejecuta un procedimiento que cambia el estado de la red, y entonces se mira cómo reacciona. A partir de esta información, se pueden deducir bastantes cosas, como errores de implementación, violaciones del protocolo, y decisiones de diseño tomadas por los implementadores.
Otra forma de verificar una implementación de TCP es analizar trazas de paquetes, o sea, capturas del tráfico que se genera al hacer una conexión. Esto permite estudiar una implementación de la que no se tiene el código fuente disponible, pero se necesitan muchas capturas para poder tener una muestra representativa de todas las situaciones posibles.

## Otras consecuencias

El hecho de usar una implementación u otra de TCP cambia algunas cosas. Además de tener errores distintos (ver sección de problemas), cada versión expone detalles internos, que pueden servir para deducir información sobre cada ordenador.

### Identificación de SO según pila TCP/IP

Debido a la evolución de TCP, actualmente hay muchas versiones distintas; unas escritas desde cero, y otras basadas en implementaciones anteriores, pero con algunos cambios. Estas variaciones entre versiones hacen que cada una se comporte de una forma algo distinta, y eso permite poder intuir qué versión está usando un ordenador a partir del comportamiento TCP que muestra. Incluso es posible hacer identificación remota del sistema operativo (fingerprinting).
Programas como el escáner de puertos nmap tienen una base de datos con la huella de cada sistema, y pueden hacer la identificación automáticamente de forma activa. Hay mucha documentación sobre este tema escrita por el autor de nmap.
Según estos documentos, las técnicas usadas para descubrir información incluyen:
* enviar un paquete FIN a un puerto abierto, y comprobar si hay respuesta (no debería según el RFC 793, pero algunas implementaciones lo hacen)
* encontrar patrones en los números de secuencia iniciales
* tomar muestras del campo ID del protocolo IP
* fijarse en los valores de tiempo de TCP (timestamp)
* ver en qué casos se activa el bit de no fragmentación (DF)
* valor de ventana inicial
* valor ACK en algunos casos especiales
* varios valores de ICMP
* tipo de servicio (ToS)
* otras opciones de TCP
En realidad, cualquier comportamiento que sea distinto entre sistemas operativos sirve para poder diferenciarlos. TCP es uno de los campos en donde hay muchas diferencias. Se pueden encontrar muchas más técnicas, y comparativas entre herramientas, en el artículo que acompaña al programa synscan:
La técnica de estudiar el número de secuencia inicial (ISN en inglés) es especialmente útil para descubrir más sobre el sistema operativo. Además, conocer el algoritmo usado tiene implicaciones para la seguridad, ya que podría permitir el IP spoofing. Pero en muchos sistemas, este número es bastante predecible (no es totalmente aleatorio). En la página se pueden ver gráficos que muestran atractores extraños de los ISN, o sea: valores a los que tiende el número de secuencia inicial usado por cada sistema.
En general, se toman pocas medidas para evitar la identificación de sistemas operativos, ya que se considera como una molestia y no como un problema de seguridad. Pero existen herramientas para evitar esta técnica, a base de intentar engañar y confundir a todo programa que intente descubrir alguna información útil. Un ejemplo para FreeBSD es:

## Bibliografía

Es especialmente útil el segundo volumen de TCP/IP Illustrated, titulado The implementation, ya que explica y muestra el código fuente de la implementación de TCP más importante (la de 4.4BSD-Lite), y explica cómo crear una implementación propia. Incluye 15.000 líneas de código C, con referencias cruzadas entre funciones, y explicaciones de algún que otro error en la versión original de BSD.