>  기사  >  백엔드 개발  >  기본 "ping" 구현을 위해 생성된 IPv4 패킷의 정확성을 어떻게 보장합니까?

기본 "ping" 구현을 위해 생성된 IPv4 패킷의 정확성을 어떻게 보장합니까?

王林
王林앞으로
2024-02-09 08:36:25948검색

如何确保为本机“ping”实现创建的 IPv4 数据包的正确性?

php 편집기 Strawberry는 로컬 "ping" 구현을 위해 생성된 IPv4 패킷의 정확성을 보장하는 방법을 소개합니다. 네트워크 통신에서는 Ping 명령을 사용하여 호스트 간의 연결을 테스트합니다. 그러나 실제 애플리케이션에서는 오류나 손실을 방지하기 위해 전송된 IPv4 데이터 패킷의 정확성을 보장해야 합니다. 이를 위해 우리는 정확한 Ping 결과를 얻을 수 있도록 데이터 패킷의 정확성과 완전성을 보장하기 위한 몇 가지 조치를 취할 수 있습니다. 다음으로 이러한 조치를 살펴보겠습니다.

질문 내용

개요

저는 본질적으로 네트워크 문제 해결 도구인 사이드 프로젝트를 진행하고 있습니다. 내 목표는 네트워킹 기본 사항을 깊이 이해하고 운영 체제에서 제공하는 문제 해결 도구를 능숙하게 사용하는 것입니다.

이것은 호스트 이름을 가져오고 문제가 있는 경우 진단을 시도하는 CLI 애플리케이션입니다. 계획은 먼저 ping과 경로 추적을 구현한 다음 점차적으로 편안함 수준에 따라 다른 도구를 구현하는 것입니다.

그러나 IPv4 패킷 형식이 잘못되어 핑 구현이 정확하지 않습니다. 이것이 Wireshark가 말하는 것입니다.

으아악

코드

이렇게 달성했습니다 ping

으아악

성찰

패킷 변형이 단일 원인인지, 복합 원인인지 잘 모르겠습니다. 문제는 다음 두 곳 중 하나(또는 둘 다?)에 있는 것 같습니다.

  1. 헤더 길이 계산이 잘못되었습니다 제가 수동으로 길이를 40 字节(wordsize = 4 字节)로 계산했습니다. 구조 손상을 방지하는 순서로 구조 필드를 작성합니다. 다양한 유형의 크기에 대한 정보는 이 소스를 참조하세요.
으아악
  1. 체크섬 계산이 잘못되었습니다인터넷 체크섬 알고리즘을 구현했습니다. 내가 여기서 해야하는 일이 이게 아니라면, 말해 주세요.

카운트 구성, 패킷에 시퀀스 번호 할당 등 구현에서 누락된 부분이 있지만 그 전에 ICMP ECHO 패킷에 대한 응답 수신과 같은 기본 구현을 수정해야 합니다. 내가 어디서 실수를 했는지 알게 되어 좋네요.

감사합니다!

2023년 8월 24일 업데이트

댓글에서 얻은 조언을 고려하여 바이트 순서를 수정하고 소스 주소, 대상 주소에 원시 바이트를 사용하도록 코드를 업데이트했습니다. 그러나 그것만으로는 문제가 해결되지 않고, 패킷의 형식이 여전히 기형이므로 다른 일이 벌어지고 있는 것이 분명합니다.

Solution

드디어 작동하게 되었습니다. 코드와 관련된 몇 가지 문제에 대해 이야기하겠습니다.

직렬화 문제

Andy가 올바르게 지적했듯이 네트워크 바이트 순서로 원시 바이트가 아닌 JSON 개체를 보냅니다. 이 문제는 binary.Write(buf, binary.BigEndian, field)

를 사용하여 수정되었습니다.

그러나 이 방법은 고정 크기 값에만 작동하기 때문에 각 구조체 필드에 대해 이 작업을 수행해야 하므로 코드가 반복적이고 다소 보기 흉해집니다.

구조 최적화와 직렬화는 다른 문제입니다.

저는 VersionIHL 字段组合在一起以优化内存的做法,这就是为什么我的结构中有这个单个字段 VersionIHL 。但是在序列化时,字段值(在本例中为 4 和 5)将被单独序列化,而我没有这样做。相反,我将整个 VersionIHL 필드의 값을 바이트로 변환하는 방법을 알고 있습니다.

결과적으로 바이트 스트림에서 예상치 못한 옥텟69,该字节流来自将 45 组合在一起的 0100 0101을 보내는 것을 발견했습니다.

불완전한 ICMP 패킷

내 ICMP 구조에는 식별자 및 시퀀스 번호 필드가 포함되어 있지 않습니다. Wikipedia의 ICMP 데이터그램 헤더 섹션에 제공된 정보는 약간 일반적인 것 같습니다. 하지만 RFC 페이지(14페이지)의 세부정보가 훨씬 더 통찰력이 있다는 것을 알았습니다.

핑 유틸리티의 일련 번호의 중요성을 고려하면 이상하게 느껴집니다. 구현하는 동안 코드에서 일련번호가 어디에 적절하게 배치되어 있는지 궁금해하는 경우가 많았습니다. 우연히 RFC 페이지를 접하고서야 비로소 일련 번호를 언제 어디서 통합해야 할지 명확한 아이디어를 얻었습니다.

관심 있으신 분들을 위해 제가 정리한 기능 코드를 소개합니다.

위 내용은 기본 "ping" 구현을 위해 생성된 IPv4 패킷의 정확성을 어떻게 보장합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 stackoverflow.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제