2016-04-04 3 views
3

Comment puis-je implémenter une découverte MTU manuelle avec Python?Envoyer du trafic IP brut avec Python: Détecter MTU

De: https://networkengineering.stackexchange.com/a/28988/23983

Envoyer un ping à une cible, dans mon exemple, je vais utiliser le serveur DNS de Google (8.8.8.8). Réglez votre bit DF sur ping to on, pour éviter que votre ping soit fragmenté. Définissez votre taille de paquet sur un grand nombre, ou la MTU standard de 1500. Notez que certaines implémentations ping définissent la taille de la charge utile, ce qui signifie que vous devez tenir compte de l'en-tête ICMP de 8 octets et de l'en-tête IP de 20 octets.

Répondre

1

Je voudrais ajouter que vous pourriez à ce avec des douilles crues aussi bien.
scapy est une belle couche d'abstraction qui fait beaucoup de magie pour vous, mais en toute équité si vous allez à la baisse, vous pourriez aller jusqu'au bout de l'expérience d'apprentissage. (Notez que les sockets premières nécessitent des autorisations élevées dans la plupart des OS'es modernes, et que vous allez les implémentations plus profondes peuvent varier de Windows et Linux.)

import socket 
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0003)) 

Cela vous donnera une prise à base de paquets bruts qui offre littéralement tous les cadres pour vous. Cela varie un peu entre Windows et Linux mais je m'en tiendrai à Linux dans cette réponse. Notez également que tous les paquets sortants peuvent ne pas être récupérés par cette socket, si vous avez besoin de cette fonctionnalité (sniffing), pensez à rechercher des hits associés à promiscuous mode.

Tout ce que vous devez faire est maintenant traiter chaque paquet comme les segments qu'ils viennent ou aller, par exemple - déballer une trame Ethernet et IP ressemblerait à quelque chose comme ceci:

frame, meta = s.recvfrom(65565) 
print(frame, meta) 

ethernet = frame[0:14] 
ethernet_segments = struct.unpack("!6s6s2s", ethernet) 

mac_source, mac_dest = (binascii.hexlify(mac) for mac in ethernet_segments[:2]) 

ip = frame[14:34] 
ip_segments = struct.unpack("!12s4s4s", ip) 

ip_source, ip_dest = (socket.inet_ntoa(section) for section in ip_segments[1:3]) 

print('MAC Source:', b':'.join(mac_source[i:i+2] for i in range(0, len(mac_source), 2))) 
print('MAC Dest:', b':'.join(mac_dest[i:i+2] for i in range(0, len(mac_dest), 2))) 
print('IP Source:', ip_source) 
print('IP Dest:', ip_dest) 

Payloading serait « facile ", considérant que vous construisez les paquets vous-même.
Que ce ne soit pas le moyen le plus conventionnel ou le moyen le plus rapide au départ, mais vous seriez en mesure de mettre en œuvre ce que vous vouliez.

L'envoi est tout aussi facile, utilisez struct et regarder les nombreux exemples ICMP là-bas, y compris ceux qui ont des calculs de contrôle:

En ce qui concerne MTU, C'est une logique que vous devez implémenter vous-même car il n'y a pas de bibliothèque préconstruite qui fait cela à ma connaissance.

Mais c'est ma contribution à l'envoi trafic IP brut avec Python.

1

Envoyer quelque chose de brut en python, vous cherchez à utiliser à l'aide de scapy.

Pour plus d'infos sur la façon d'envoyer des messages ping:

http://www.secdev.org/projects/scapy/doc/usage.html#icmp-ping

Pour définir le drapeau DF:

IP(flags='DF') 

Pour savoir comment régler la taille particulière de sorte que vous pouvez simuler la fragmentation:

Adding payload in packet (scapy)

Mettre tous ensemble:

data = "x" * 1473 
ans,unans = sr(IP(dst="<target_ip>", flags='DF')/ICMP()/Raw(load=data)) 

Si vous n'êtes pas réellement intéressé à la création de ces choses premières, cette question est un dup de: How to find mtu value of network through code(in python)?