Giới thiệu về giao thức ICMP (Internetwork Control Message Protocol)
Hoạt động ở layer 2 – Internetwork trong mô hình TCP/IP hoặc layer 3 – Network trong mô hình OSI
Cho phép kiểm tra và xác định lỗi của layer 2 trong mô hình TCP/IP bằng cách định nghĩa ra các loại thông điệp có thể sử dụng để xác định xem mạng hiện tại có thể truyền được gói tin hay không?
ICMP cần các thành phần của mọi gói tin IP để có thể hoạt động được
Mục đích của ICMP: Thỉnh thoảng một gateway hoặc một máy đích sẽ liên lạc với máy nguồn để đưa ra những thông điệp lỗi về tiến trình xử lý các gói tin.
ICMP sử dụng với một mục đích đơn giản là hỗ trợ cho sự hoạt động của giao thức IP
29 trang |
Chia sẻ: Mr Hưng | Lượt xem: 927 | Lượt tải: 0
Bạn đang xem trước 20 trang nội dung tài liệu Lập trình mạng nâng cao icmp protocol, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
ICMP PROTOCOLLẬP TRÌNH MẠNG NÂNG CAO1Nguyễn VũICMP protocolGiới thiệu về giao thức ICMP (Internetwork Control Message Protocol)Hoạt động ở layer 2 – Internetwork trong mô hình TCP/IP hoặc layer 3 – Network trong mô hình OSICho phép kiểm tra và xác định lỗi của layer 2 trong mô hình TCP/IP bằng cách định nghĩa ra các loại thông điệp có thể sử dụng để xác định xem mạng hiện tại có thể truyền được gói tin hay không?ICMP cần các thành phần của mọi gói tin IP để có thể hoạt động đượcMục đích của ICMP: Thỉnh thoảng một gateway hoặc một máy đích sẽ liên lạc với máy nguồn để đưa ra những thông điệp lỗi về tiến trình xử lý các gói tin.ICMP sử dụng với một mục đích đơn giản là hỗ trợ cho sự hoạt động của giao thức IP 2Nguyễn VũICMP protocolGiới thiệu về giao thức ICMP (Internetwork Control Message Protocol)3Nguyễn VũICMP protocolGiới thiệu về giao thức ICMP (Internetwork Control Message Protocol)Cấu trúc của gói tin IP và ICMP4Nguyễn VũICMP protocolGiới thiệu về giao thức ICMP (Internetwork Control Message Protocol)Cấu trúc của gói tin IP và ICMPType: dài 1 byte định nghĩa kiểu thông điệp ICMP trong gói tinCode: dài 1 byte định nghĩa thêm về kiểu, xác định đây là một query hay một lỗiChecksum: dài 2 byte cho biết gói ICMP không bị sai lạc thông tin. Checksum được tính toán trên phần ICMP của gói dùng thuật toán được định nghĩa trong RFC 792 Messeage: gồm nhiều byte có nội dung phù hợp với kiểu thông điệp ICMP. Thường có chứa 2 trường là số Identifier và Sequence dùng để xác định duy nhất gói ICMP packet đến host. 5Nguyễn VũICMP protocolThe ICMP Packet Types:Type CodeDescription0Echo reply3Destination unreachable4Source quench5Redirect8Echo request11Time exceeded12Parameter problem13Timestamp request14Timestamp reply15Information request16Information reply6Nguyễn VũICMP protocolSử dụng Raw socket:Gói tin ICMP không sử dụng TCP hoặc UDP nên chúng ta không thể sử dụng lớp hỗ trợ TcpClient hay UdpClient mà sử dụng một Raw Socket.Muốn sử dụng Raw Socket khi tạo ra Socket ta sử dụng SocketType.Raw và giao thức là ICMPTrong C# để tạo Raw socket ta dùng cú pháp sau: Socket newSocket= new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);7Nguyễn VũICMP protocolGửi gói tin Raw socket:Là giao thức không hướng kết nối, không cần bind socket đến cổng cục bộ để gởi gói tin hoặc dùng phương thức Connect() để nối nó với host cụ thể ở xa Sử dụng phương thức SendTo() của lớp Socket để gửi.Cổng trong giao thức ICMP không quan trọngSocket newsock= new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);IPEndPoint iep = new IPEndPoint(IPAddress.Parse("192.168.1.2"), 0);newsock.SendTo(packet,iep);8Nguyễn VũICMP protocolGửi gói tin Raw socket:Chú ý: Vì raw socket không format dữ liệu nên mảng byte sẽ truyền “đúng y” đến host ở xa. Do đó bạn phải tạo thủ công gói ICMP thành mảng byte rồi mới gởi. Nếu có lỗi bạn sẽ không có gói ICMP trả về.9Nguyễn VũICMP protocolNhận gói tin Raw socket:Dữ liệu nhận được từ raw socket phức tạp hơn, ta phải dùng phương thức ReceiveFrom(). Raw socket không xác định giao thức tầng trên, dữ liệu trả về của phương thức ReceiveFrom() chứa toàn bộ nội dung gói IP. Chú ý: Vì phương thức ReceiveFrom() cho toàn bộ gói IP, ta phải khai báo kích thước buffer nhận nhiều hơn dữ liệu chứa bên trong ít nhất là 20 bytes.10Nguyễn VũICMP protocolTạo lớp ICMP ClassTạo lớp ICMP Class để dễ dùng trong các ứng dụng mạng có các gói ICMP. Cấu tử lớp ICMP ClassLớp ICMP thường cần có các biến dữ liệu trong bảng sau:VariableSizeTypeType1 byteByteCode1 byteByteChecksum2 bytesUnsigned 16-bit integerMessagemultibyteByte array11Nguyễn VũICMP protocolTạo lớp ICMP ClassKhông gán giá trị cho các biến dữ liệu. Bạn sẽ gán giá trị cho chúng khi thực sự tạo gói ICMP class ICMP{ public byte Type; public byte Code; public UInt16 Checksum; public int MessageSize; public byte[] Message = new byte[1024]; public ICMP() { }}12Nguyễn VũICMP protocolTạo lớp ICMP ClassĐể tạo nên gói ICMP mới, ta khai báo và gán giá trị như sau:ICMP packet = new ICMP();packet.Type = 0x08;packet.Code = 0x00;packet.Checksum = 0;Đoạn code trên tạo phần đầu của gói ICMP Echo Request.Gói Echo Request định nghĩa các trường trong thành phần thông điệp ICMP (Identifier và Sequence), bạn phải quyết định xây dựng thành phần này như thế nào. Có 2 cách:Tạo lớp khác cho trường Echo Request và lấy mảng byte của lớp.Chuyển các trường thông điệp riêng thành mảng byte và đặt chúng vào thành phần dữ liệu. 13Nguyễn VũICMP protocolTạo lớp ICMP ClassNếu bạn định tạo nhiều gói Echo Request, bạn nên tạo lớp Ping định nghĩa các trường Echo Request riêng biệt.Ngược lại bạn làm như sau:Buffer.BlockCopy(BitConverter.GetBytes((short)1),0, packet.Message, 0, 2);Buffer.BlockCopy(BitConverter.GetBytes((short)1), 0, packet.Message, 2, 2);byte[] data = Encoding.ASCII.GetBytes("test packet");Buffer.BlockCopy(data, 0, packet.Message, 4, data.Length);packet.MessageSize = data.Length + 4;Các trường Identifier và Sequence cho gói Echo Reply lần lượt chuyển thành mảng byte và đặt đúng vị trí trong thành phần thông điệp14Nguyễn VũICMP protocolXây dựng lại đối tượng ICMP ObjectSau khi gởi gói ICMP, bạn thường sẽ nhận lại gói ICMP của thiết bị ở xa trả về. Để dễ lấy nội dung của gói đó, bạn nên tạo lớp ICMP khởi dựng khác để lấy mảng byte ICMP và đặt giá trị vào thành phần dữ liệu phù hợp trong lớp :public ICMP(byte[] data, int size){ Type = data[20]; Code = data[21]; Checksum = BitConverter.ToUInt16(data, 22); MessageSize = size - 24; Buffer.BlockCopy(data, 24, Message, 0, MessageSize);}15Nguyễn VũICMP protocolXây dựng lại đối tượng ICMP ObjectNhớ là raw socket trả về toàn bộ gói IP. Như vậy bạn phải bỏ qua thông tin IP header trước khi trích thông tin gói ICMP. Thành phần Type ở vị trí 20 trong mảng byte. Các thành phần dữ liệu riêng biệt trong gói ICMP được trích theo từng byte vào thành phần ICMP phù hợp.16Nguyễn VũICMP protocolXây dựng lại đối tượng ICMP ObjectSau khi tạo đối tượng ICMP mới với dữ liệu gói nhận được, bạn có thể xem các thành phần dữ liệu riêng biệt:int recv = ReceiveFrom(data, ref ep);ICMP response = new ICMP(data, recv);Console.WriteLine("Received ICMP packet:");Console.WriteLine(" Type {0}", response.Type);Console.WriteLine(" Code: {0}", response.Code);Int16 Identifier = BitConverter.ToInt16(response.Message, 0);Int16 Sequence = BitConverter.ToInt16(response.Message, 2);Console.WriteLine(" Identifier: {0}", Identifier);Console.WriteLine(" Sequence: {0}", Sequence);stringData = Encoding.ASCII.GetString(response.Message, 4, response.MessageSize - 4);Console.WriteLine(" data: {0}", stringData);17Nguyễn VũICMP protocolXây dựng lại đối tượng ICMP ObjectNhận được 2 thành phần dữ liệu đầu trong gói ICMP nhận là dễ.Trích các trường dữ liệu trong thành phần thông điệp hơi khó hơn. Vì 2 bytes đầu tạo trường số nguyên không dấu Identifier và 2 bytes thứ hai là trường số nguyên không dấu Sequence, bạn có thể dùng lớp BitConverter để gán các giá trị đó. Phần còn lại của thành phần thông điệp được gán cho trường Message của gói Echo Reply packet.Từ đoạn code này, bạn dễ thấy vì sao thành MessageSize được thêm vào lớp ICMP. Nếu không có nó, sẽ khó xây dựng lại thành phần Message từ gói nhận được.18Nguyễn VũICMP protocolThe ICMP Packet CreatorSau khi đối tượng ICMP mới được tạo ra và các thành phần dữ liệu gói được xác định, bạn muốn gởi gói đến thiết bị ở xa. Bạn không thể gởi đối tượng ICMP bằng phương thức SendTo(); cần chuyển nó thành mảng byte.Cách dễ nhất để gởi đối tượng phức tạp qua mạng là tạo phương thức chuyển mỗi thành phần dữ liệu thành mảng byte và nối các mảng lại thành mảng byte lớn hơn dùng phương thức Buffer.BlockCopy(): 19Nguyễn VũICMP protocolThe ICMP Packet Creatorpublic byte[] getBytes(){ byte[] data = new byte[MessageSize + 9]; Buffer.BlockCopy(BitConverter.GetBytes(Type), 0, data, 0, 1); Buffer.BlockCopy(BitConverter.GetBytes(Code), 0, data, 1, 1); Buffer.BlockCopy(BitConverter.GetBytes(Checksum), 0, data, 2, 2); Buffer.BlockCopy(Message, 0, data, 4, MessageSize); return data;}20Nguyễn VũICMP protocolThe ICMP Packet CreatorKhi tất cả các thành phần dữ liệu được chuyển thành mảng byte có đúng dạng gói ICMP có thể nó đến thiết bị mạng ở xa: IPEndPoint iep = new IPEndPoint(IPAddress.Parse("192.168.1.2"), 0);sock.SendTo(packet.getBytes(), iep);Chú ý: Giá trị Identifier và Sequence không được chuyển thành byte trước khi đưa vào mảng vì thiết bị mạng ở xa sẽ trả về cho bạn gói y hệt.21Nguyễn VũICMP protocolPhương pháp tính ICMP ChecksumĐây là phần khó nhất khi tạo ra gói ICMP packet. Cách làm là tạo phương thức tự chứa tính checksum và đưa vào lớp ICMP phục vụ cho ứng dụng ICMP. Có vài ví dụ tính checksum, sau đây là ví dụ:22Nguyễn VũICMP protocolPhương pháp tính ICMP Checksumpublic UInt16 getChecksum() { UInt32 chcksm = 0; byte[] data = getBytes(); int packetsize = MessageSize + 8; int index = 0; while ( index > 16) + (chcksm & 0xffff); chcksm += (chcksm >> 16); return (UInt16)(~chcksm); }23Nguyễn VũICMP protocolPhương pháp tính ICMP ChecksumĐầu tiên gán đầy giá trị tất cả thành phần dữ liệu, đặt thành phần Checksum thành zero. Sau đó, gọi phương thức getChecksum() để tính checksum của gói ICMP, đặt kết quả vào thành phần Checksum của gói: packet.Checksum = 0;packet.Checksum = packet.getChecksum();Sau khi tính xong Checksum gởi gói đi sử dụng phương thức SendTo(). Chú ý: Khi nhận gói ICMP bạn phải lấy giá trị Checksum và so sánh với giá trị đã tính cho gói. Nếu 2 giá trị không so khớp, đã có lỗi và cần truyền lại gói.24Nguyễn VũICMP protocolSau đây là chương trình ICMP.cs đầy đủ:25Nguyễn VũICMP protocolA Simple Ping Program :Ping là công cụ căn bản, quan trọng cho biết thiết bị có kết nối mạng không. Nó dùng gói ICMP Echo Request (Type 8) để gởi đến host ở xa. Host ở xa nhận thông điệp, trả lời bằng gói ICMP Echo Reply (Type 0), có chứa thông điệp ban đầu:26Nguyễn VũICMP protocolChương trình ICMPPing:Chương trình SimplePing có một số hạn chế:Địa chỉ đích phải gõ dạng IPChỉ có gởi và nhận được 1 thông điệp ping. Không quy định kích thước dữ liệu pingThời gian thực hiện lệnh ping không được ghi lại.Để khắc phục, ta viết chương trình AdvPing.cs cho phép người dùng gõ vào địa chỉ IP hoặc hostnames trong hộp text, dùng phương thức Dns.Resolve()27Nguyễn VũICMP protocolAn Advanced Ping Program Phương thức Dns.Resolve() sẽ trả về mảng IPHostEntry. Mảng IPHostEntry chứa tất cả các địa chỉ IP liên kết với hostname hoặc IP: IPHostEntry iphe = Dns.Resolve(hostbox.Text);IPEndPoint iep = new IPEndPoint(iphe.AddressList[0], 0);Để cho phép nhiều gói ping, AdvPing dùng luồng (Thread) riêng để quản lý chức năng ping thực sự. Khi người dùng kích nút Start sẽ sinh ra 1 luồng mới. Luồng mới chứa vòng lặp ping liên tục đến host ở xa cho đến khi luồng hủy bỏ. Do đó, giao diện người dùng gồm có 1 nút lệnh để người dùng kích vào kết thúc ping.Mỗi gói ping ICMP gởi đi được gán 1 số Sequence liên tiếp nhau nhằm chỉ các gói ping riêng biệt. Vì số Sequence cho mỗi gói thay đổi giá trị ICMP checksum cần tính lại cho mỗi gói.28Nguyễn VũICMP protocolChương trình Advanced Ping:29Nguyễn Vũ
Các file đính kèm theo tài liệu này:
- baigianglaptrinhmangnangcaonguyenvu_icmp_7934.ppt