IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Découpage trame ethernet c++


Sujet :

C++

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Etudiant en apprentissage
    Inscrit en
    Avril 2022
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Etudiant en apprentissage
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2022
    Messages : 1
    Points : 1
    Points
    1
    Par défaut Découpage trame ethernet c++
    Bonjour à tous,

    Je viens vers ici dans l'espoir d'une réponse pour me guider.

    En effet, dans le but de mon apprentissage, je dois récupérer une trame Ethernet, la stocker et l'écrire dans un fichier.

    Cependant, pour l'écriture, j'écris ma trame ethernet en hexa, ligne par ligne, dans un stringstream. Mais je n'arrive pas à découper celle-ci, car il faut que j'insère un espace après chaque "mots" de n octets (1 octets = 4 caractères). Dans cette trame, j'ai donc 52 mots. Les 7 premiers mots sont sur 4 octets chacun, les 36 suivant sont sur 2 octets chacun, puis 1 mot sur 52 octets (bourrage ou réserve pour futur utilisation) et enfin, j'ai un dernier mot sur 2 octets et les 8 derniers mots sont sur 4 (1 mot), 16 (1 mots) et 2 octets. Au total ma trame fait 188 octets.

    Je ne sais donc pas comment récupérer mon stringstream, puis parcourir chaque ligne en modifiant chacune d'entre elle pour lui donner le bon format.

    J’espère avoir été assez précis.

    Dans l'espoir d'avoir une réponse,

    En vous remerciant d'avance.

  2. #2
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 361
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 361
    Points : 20 379
    Points
    20 379
    Par défaut
    salut au besoin se documenter sur les champs de bit
    https://en.wikipedia.org/wiki/Bit_field
    Mais sinon rien qu'avec les fonctionnalités de std::string ça suffit largement.
    Mais je n'arrive pas à découper celle-ci, car il faut que j'insère un espace après chaque "mots" de n octets (1 octets = 4 caractères).
    Où est le problème ? Avec std::string c'est faisable.
    Il faudrait nous donner du code

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    j'ai l'impression que ton principal problème est de faire une sérieuse soupe entre les notions de caractères et de valeurs d'une part et entre les notions de "décimale" et de "hexadécimale" d'autre part.

    Car, pour ce qui est de la première partie, il faut savoir que '1' (le caractère, le "glyphe" qui représente le chiffre 1) ... n'est pas égal à la valeur numérique 1.

    Le "glyphe" qui représente le chiffre 1, on le retrouve à la position 49 de la table ASCII, qui est la table couramment utilisée pour permettre l'affichage à l'écran (ou l'inscription dans un fichier). Cela signifie que si tu venais à écrire un code proche de std::cout<< (char)49 (ce code est horrible, mais il sert tellement bien mon exemple ) tu verrais apparaitre ... le chiffre 1.

    Pourquoi parce que ce code demande explicitement à l'ordinateur d'afficher le caractère auquel la valeur (numérique) 49 est associée, et que l'ordinateur va donc aller voir dans la table de caractères qu'il utilise (la table ASCII) le glyphe qui se trouve... à la position 49 et qui n'est rien d'autre que le glyphe qui représente le chiffre 1.

    D'un autre coté,les notions de "décimale" et de "hexadécimale" sont ce que l'on appelle des "bases de calcul". La base décimale, c'est celle que nous utilisons "tous les jours", celle qui va utiliser les chiffre de 0 à 9 pour faire nos calculs courrents: (3 + 4) * 5 = 35.

    La base hexadécimale, quant à elle, ne va pas utiliser dix chiffres, mais ... 16. Bien sur, on n'a pas de "chiffre particulier" pour représenter les valeurs comprises entre 11 et 15 inclue. On va donc prendre les lettres qui existent déjà: A, B, C, D, E et F.

    L'hexadécimal a ceci d'intéressant qu'il "s'aligne" parfaitement avec le nombre de valeurs susceptibles d'être représentée lorsque l'on a quatre "points de contact" où le courant peut passer ou non (ce qui est --grosso modo -- la définition d'un bit). En effet, si on prend quatre bits ensemble, on dispose de 24 = ... 16 possibilités, ce qui correspond exactement au nombre de possibilités que nous donnent nos dix chiffres "classiques" (0,1,2,3,4,5,6,7,8 et 9) auxquelles on a ajouté les six première lettres de l'alphabet.

    Pour faire la différence entre la notation (la "représentation" d'une valeur à l'écran ou dans un fichier ) décimale et la notation hexadécimale, on a "simplement" décidé (par convention) de rajouter le préfixe 0x pour indiquer clairement que nous utilisons la représentation hexadécimale.

    Cependant, nous pourrons sans aucun problème représenter exactement les mêmes valeurs numériques! Il y a parfaite équivalence de valeur entre les différentes bases de calcul. Un peu comme le terme "arbre" en Français: un anglais parlera de "tree" et un néeralandophone parlera de "boom", et pourtant, ils parleront tous les trois de la même chose

    hé bien, ici, c'est pareil: si tu veux afficher la valeur 15 en décimale, tu affichera "15", mais si tu veux l'afficher sous la forme hexadécimale, tu l'affichera sous la forme de "0x0F" voire, si tu pars du principe et de la convention que l'affichage se fait ** forcément ** en hexadécimale, sous la forme de F.

    Ainsi, si tu veux afficher la valeur (décimale) 103 en hexadécimale, tu l'affichera sous la forme de (0x)63.

    On pourrait même s'amuser à trouver le moyen de "convertir" une valeur décimale en valeur hexadécimale et vice-versa. L'algorithme à mettre en place est particulièrement simple. Mais bon, ce n'est pas la chose la plus importante à faire, car, du fait même que l'ordinateur ne connait que le binaire (le courant passe ou ne passe pas à un endroit donné), il va "naturellement" convertir nos valeurs décimales en binaire, ce qui le mettra dans une excellente position pour manipuler les valeurs numériques sous leur forme hexadécimale

    Bon, tout cela, c'est un peu la théorie, et j'espère t'en avoir "assez dit" que pour te permettre de comprendre le principe. Car il y a une chose encore plus importante à comprendre et que tu auras beaucoup plus facile à comprendre cette chose si tu as compris la différence entre binaire, décimale et hexadécimale et la différence entre la notion de caractère et celle de valeur numérique.

    Commençons par le plus simple, et pourtant sans doute la chose la plus "contre intuitive" parmi toutes choses contre intuitives que l'on peut envisager: les données que l'on manipule à partir de l'ordinateur ne signifie absolument rien pour lui.

    Que nous manipulions des couleurs, des sons, des images ou même les instructions que l'on va demander à l'ordinateur d'exécuter, l'ordinateur, lui, ne verra jamais qu'une seule et unique chose: une succession plus ou moins grande de points où il pourra aller tester si le courant passe (ou non) à un moment donné.

    C'est parce que nous (les humains qui utilisons l'ordinateur), nous allons décider d'interpréter cette succession plus ou moins grande de bits d'une manière bien particulière que nous serons en mesure de demander à l'ordinateur d'exécuter "tel ensemble d'instructions", destinées à la manipulation de "tel type bien particulier de donnée" au lieu d'effectuer "tel autre ensemble d'instructions" qui serait lui adapté à la manipulation de "tel autre type de donnée.

    Mais il faut comprendre que cette notion de "type de donnée particulier", elle n'a vraiment de l'intérêt que pour nous (les humains qui utilisons l'ordinateur).

    Alors, j'espère non seulement t'avoir convaincu par cette explication, mais surtout que tu as compris l'idée que j'essayais de faire passer, car, si c'est le cas, le point suivant te paraitra parfaitement logique

    Il faut savoir que la manière dont nous allons afficher les données n'est au final que la représentation des données que l'on va nous donner (à nous, humains qui utilisons l'ordinateur) dans l'espoir que nous soyons en mesure de ... les interpréter correctement le plus facilement possible.

    Mais revenons à ta description de la trame ethernet. Tu nous dis
    Cependant, pour l'écriture, j'écris ma trame ethernet en hexa, ligne par ligne, dans un stringstream. Mais je n'arrive pas à découper celle-ci, car il faut que j'insère un espace après chaque "mots" de n octets (1 octets = 4 caractères). Dans cette trame, j'ai donc 52 mots. Les 7 premiers mots sont sur 4 octets chacun, les 36 suivant sont sur 2 octets chacun, puis 1 mot sur 52 octets (bourrage ou réserve pour futur utilisation) et enfin, j'ai un dernier mot sur 2 octets et les 8 derniers mots sont sur 4 (1 mot), 16 (1 mots) et 2 octets. Au total ma trame fait 188 octets.
    Oh là là... tu es occupé à nous faire une fameuse soupe là

    Oublions donc un instant que tu veux représenter ta trame internet d'une manière "compréhensible pour toi" à l'écran, et posons nous une question simple: combien d'octets la trame ethernet que tu obtiens fait elle

    Si j'ai bien compris ton explication -- et que j'ai bien compté -- tu reçois 152 octets à chaque trame, est-ce bien cela

    Hé bien, dis toi que la représentation la plus proche de la réalité que nous pourrions nous faire de la représentation de cette trame de 152 octets en mémoire, ce serait ... une succession de 152*8 = 1024 "1" et "0" qui se suivent.

    Mais cette représentation est déjà une certaine forme d'interprétation, car le "1" représenterait un bit par lequel le courant passe, et le "0" représenterait un bit par lequel le courant ne passe pas.

    Et bien sur, cette représentation aurait beau être la plus proche de la manière dont ta trame est représentée en mémoire, ce n'est certainement pas la représentation qui nous permettrait -- à nous "pauvres humains" -- de comprendre le contenu de la trame le plus facilement

    Essayons donc de "compacter" un peu cet affichage. Pour ce faire, nous allons travailler en deux temps:

    D'abord, nous "regroupons" tous les bits par "groupe de 8", ce qui nous permet d'obtenir ce que l'on appelle "des octets". Nous obtenons donc ... 152 groupes de 8 bits, mais là, je ne fais que revenir en arrière.

    Ensuite, nous décidons d'utiliser la notation hexadécimale pour représenter la valeur de chaque octet et, pour éviter les problèmes qui seraient éventuellement liés au fait qu'un octet puisse représenter une valeur numérique inférieure à 16, nous décidons d'utiliser systématiquement un "symbole" (les chiffres et les lettres) par "demi octet" (par groupe de 4 bits).

    De cette manière, que si nous avons un octet dont la valeur numérique équivaut à 15, nous afficherons 0F au lieu d'afficher simplement F. Mais ca, c'est juste une convention que l'on choisi d'appliquer "pour notre propre facilité", car elle va nous permettre de voir directement que nous avons trois octets (valant chacun 15) avec un affichage proche de0F0F0F alors que, autrement l'affichage FFF nous laissait nous poser la question de la manière dont il fallait l'interpréter: est-ce
    • 3 octets valant chacun 15
    • un octet valant 255 suivi d'un octet valan 15 ou
    • un octet valant 15 suivi d'un octet valant 255

    Parce que les trois possibilités auraient été "plausibles" et que chacune d'elle aurait eu une signification différente au niveau de la trame.

    NOTA: Nous n'ayons choisi l'affichage sous une forme hexadécimale finalement que parce que c'est la représentation la plus "compacte" et pourtant la "plus facile à interpréter" dont nous disposions.

    Nous nous retrouvons en effet avec l'affichage de 254 "glyphes", que nous pourrions "grouper par 2", alors que si on avait choisi d'afficher ces valeurs sous une forme décimale, nous aurions eu besoin de ... trois "glyphes" par octet, vu qu'il aurait fallu représenter des valeur allant de 0 à ... 255 et que nous aurions de toutes façons été confrontés à un problème tout à fait similaire (mais sur trois glyphes au lieu de deux) à celui que je viens d'expliquer.

    Une dernière solution aurait d'ailleurs pu nous traverser l'esprit, car nous savons maintenant que un octet (un groupe de huit bits consécutifs) permet de représenter "n'importe quelle place valide" dans la table ASCII. Il n'y aurait donc qu'un pas à franchir pour se dire que "ce serait encore plus compact et donc plus compréhensible si nous demandions simplement d'afficher le glyphe associé à chaque valeur dans la table ASCII", n'est-ce pas

    Hé bien non... Et pour plusieurs raisons:
    • D'abord, les glyphes associés aux valeurs comprises entre 128 et 255 ne sont pas les même partout: il n'y a vraiment que pour les valeurs comprises entre 0 et 127 (inclus) qui ne changeront jamais.
    • Ensuite parce qu'il y a une série de caractères qui n'ont pas vocation à être affichés. Ce sont les caractères associés aux valeur comprises entre 0 et 31 (inclus) ainsi que le caractère associé à la valeur 127.
    • Enfin, et surtout, parce que ces caractères qui "n'ont pas vocation à être affichés" ont chacun une signification particulière pour le système qui s'occupe de l'affichage justement. Si on essaye de les afficher nous même, on risque d'avoir des résultat ... plutôt surprenants

    (essaye de compiler et d'exécuter -- après avoir mis le casque et poussé le volume à fond -- un code contenant std::cout<<(char)7; pour t'en convaincre... C'est le plus marrant bien que sans grand danger )

    Mais revenons à nos moutons: nous avons donc potentiellement 152 groupes de 2 glyphes qui représentent l'ensemble des octets de la trame sans que nous n'ayons cherché à les interpréter d'une quelconque manière.

    La question qu'il serait sans doute intéressant de se poser est : cette représentation est-elle "suffisamment facile à interpréter" par celui qui devra l'interpréter

    Si la réponse est oui, sincèrement, je ne vois pas trop pourquoi nous voudrions nous faire du mal en essayant de faire plus complexe que cela

    Et, pour être tout à fait honnête, je dirais volontiers que nous devrions nous arrêter là, car on a déjà fait le plus gros: on a récupéré la trame éthernet et on en donne une représentation "suffisamment compacte" que pour pouvoir être interprétée au besoin. Avoue que c'est déjà pas si mal, non?

    D'autant plus que, si tu décide d'analyser cette trame "plus en profondeur", si tu décide de t'intéresser à la signification de chaque (groupe d') octet(s) de la trame, tu seras sans doute intéressé par le fait d'afficher ta trame dans quelque chose "d'un peu plus maniable" que ta console de commande.

    En nous arrêtant ici, nous nous arrêterions en fait "juste avant" de commencer à appliquer des changements susceptibles d'interférer avec les outils utilisés pour l'interprétation de la trame.

    Bien sur, nous pourrions décider de séparer les différents groupes d'octets que ta trame contient d'un tas de manière différentes. J'espère que tu auras désormais compris que cela ne ferait que changer ... la représentation de ta trame que tu propose à l'utilisateur. Et rien ne serait impossible à défaire en cas de besoin (par exemple, si l'utilisateur souhaite utiliser un outil "plus sympathique" pour analyser la trame).

    La question est: est ce que cela vaut vraiment la peine ne pourrait on pas suivre le principe "wait and see" des anglais, et nous dire que nous pourrions "tout aussi bien" attendre d'avoir la certitude que l'utilisateur veut utiliser la sortie console pour analyser la trame avant de lancer la transformation qui lui permettra de le faire de manière sympa

    Cette question, moi, je la laisse en suspend pour l'instant, car c'est à toi que revient la décision Mais, au moins, si tu as compris l'ensemble de ce roman (et sinon, n'hésite pas à le relire plusieurs fois ou meme à poser des questions supplémentaires ) tu ne devrais plus t'embrumer le cerveau avec des questions qui n'en valent pas vraiment la peine
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Analyseur de trames Ethernet
    Par Zay dans le forum Réseau
    Réponses: 3
    Dernier message: 04/12/2006, 23h17
  2. [libpcap]Analyse de trame Ethernet
    Par Zay dans le forum Développement
    Réponses: 1
    Dernier message: 30/11/2006, 12h27
  3. Analyse de trame Ethernet
    Par totore dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 24/10/2006, 16h15
  4. Obtenir une trame Ethernet
    Par Scorff dans le forum Développement
    Réponses: 15
    Dernier message: 11/09/2006, 12h22
  5. Trame Ethernet
    Par yokiyok dans le forum Windows
    Réponses: 3
    Dernier message: 03/11/2004, 07h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo