Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции.docx
Скачиваний:
12
Добавлен:
15.03.2015
Размер:
5.82 Mб
Скачать

Лекция 8

8.1. Структуры

Под структурами понимают группу переменных, объединенных общим именем. Структуры широко применяются при описании сообщений, которыми обмениваются сетевые элементы. Удобство структуры заключается в том, что они позволяют группировать разнородные данные.

Объявление структуры начинается с ключевого слова struct. Синтаксис структуры следующий:

struct

{тип_переменной_1 имя переменной_1;

тип_переменной_2 имя переменной_2;

. . .

тип_переменной_n имя переменной_n;

}имя_структуры;

Для примера рассмотрим заголовок IP-пакета версии 4.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

Данные (Data)

Опции и заполнение (Options + Padding)

Адрес назначения (Destination Address)=0xc0a801ca

Адрес источника (Source Address)=0xa3f2cb32

Время жизни=0x7f

(Time to Live)

Протокол=0x11

(Protocol)

Контрольная сумма=0x710f

(Header Checksum)

Идентификатор (Identification)=0x987e

Флаги=0

(Flags)

Смещение фрагмента=0

(Fragment Offset)

Версия=4

(Version)

Длина=5

(IHL)

Тип услуги=0

(Type of Service)

Общая длина=0x00с8

(Total Length)

2 уровень

1 уровень

Рис. 8.1. Формат заголовка IPv4

Назначение полей пакета следующее.

Версия (Version) – определяет версию протокола, длина 4 бита, для версии 4 Version=4 (двоичный код 0100).

Длина заголовка (Internet Header LengthIHL) – определяет длину заголовка в 32-х битных словах, длина 4 бита.

Тип услуги (Type of ServiceTOS) – длина 8 бит, задает приоритетность обслуживания пакета и критерий выбора маршрута.

Общая длина пакета (Total Length) – определяет длину пакета (заголовок + данные) в байтах, длина 16 бит.

Идентификатор (Identification) – указывает на принадлежность пакета к определенной дейтаграмме, длина 16 бит. Все фрагменты (пакеты) одной дейтаграммы должны иметь одно и то же значение.

Флаги (Flags) – содержат признаки фрагментации, длина 3 бита.

Смещение фрагмента (Fragment Offset - FO) – указывает на положение пакета относительно начала дейтаграммы, длина 13 бит.

Время жизни (Time to LiveTTL) – определяет предельный срок перемещения пакета по сети, длина 1 байт.

Протокол (ProtocolProt) – указывает на протокол, которому следует доставить (или от которого поступила) информация.

Контрольная сумма заголовка (Header Checksum) – используется для обнаружения ошибок принятого пакета, длина 16 бит. Формируется так, чтобы сумма всех 16-разрядных слов заголовка с учетом переноса, включая контрольную сумму, давала бы FFFF.

Адрес источника (Source Address) – определяет сетевой адрес (IP-адрес) отправителя пакета, длина 32 бита.

Адрес назначения (Destination Address) – определяет сетевой адрес получателя, длина 32 бита.

Опции (Options) – это поле может отсутствовать, имеет переменную длину. Обычно используется при отладке сети.

Заполнение (Padding) – содержит заполнение пакета “нулями” так, чтобы общая длина пакета была кратна 32 бит.

В поле данных (Data) размещаются информация пользователя.

Структура приведенного заголовка IP-пакета выглядит следующим образом.

#include <iostream>

#include <windows.h>

#include <cstring>

using namespace std;

struct //Header description

{

struct

{

unsigned int version: 4;

unsigned int length: 4;

}version;

int type_of_service;

struct

{

unsigned int length_1: 8;

unsigned int length_2: 8;

}total_length;

struct

{

int unsigned ident_1: 8;

int unsigned ident_2: 8;

}identification;

struct

{

unsigned int flags: 3;

unsigned int offset: 5;

}flag_fragment;

int time_to_live;

int protocol;

struct

{

unsigned int check_1: 8;

unsigned int check_2: 8;

}header_checksum;

struct

{

unsigned int address_1: 8;

unsigned int address_2: 8;

unsigned int address_3: 8;

unsigned int address_4: 8;

}source_address;

struct

{

unsigned int address_1: 8;

unsigned int address_2: 8;

unsigned int address_3: 8;

unsigned int address_4: 8;

}destination_address;

}ip_header;

int main()

{

//Header initialization 4500 00c8 987e 0000 7f11 710f a3f2 cb32 c0a8 01ca.

ip_header.version.version=4; //ip_word[1]

ip_header.version.length=5;

ip_header.type_of_service=0;

ip_header.total_length.length_1=0; //ip_word[2]

ip_header.total_length.length_2=200;

ip_header.identification.ident_1=152; //ip_word[3]

ip_header.identification.ident_2=126;

ip_header.flag_fragment.flags=0; //ip_word[4]

ip_header.flag_fragment.offset=0;

ip_header.time_to_live=127; //ip_word[5]

ip_header.protocol=17;

ip_header.header_checksum.check_1=113; //ip_word[6]

ip_header.header_checksum.check_2=15;

ip_header.source_address.address_1=163; //ip_word[7]

ip_header.source_address.address_2=242;

ip_header.source_address.address_3=203; //ip_word[8]

ip_header.source_address.address_4=50;

ip_header.destination_address.address_1=192; //ip_word[9]

ip_header.destination_address.address_2=168;

ip_header.destination_address.address_3=1; //ip_word[10]

ip_header.destination_address.address_4=202;

//Transfer header view

int ip_word[20];

ip_word[1]=(ip_header.version.version<<12)+(ip_header.version.length<<8)+ip_header.type_of_service;

cout<<hex<<ip_word[1]<<endl;

ip_word[2]=(ip_header.total_length.length_1<<8)+ip_header.total_length.length_2;

cout<<hex<<ip_word[2]<<endl;

ip_word[3]=(ip_header.identification.ident_1<<8)+ip_header.identification.ident_2;

cout<<hex<<ip_word[3]<<endl;

ip_word[4]=(ip_header.flag_fragment.flags<<13)+ip_header.flag_fragment.offset;

cout<<hex<<ip_word[4]<<endl;

ip_word[5]=(ip_header.time_to_live<<8)+ip_header.protocol;

cout<<hex<<ip_word[5]<<endl;

ip_word[6]=(ip_header.header_checksum.check_1<<8)+ip_header.header_checksum.check_2;

cout<<hex<<ip_word[6]<<endl;

ip_word[7]=(ip_header.source_address.address_1<<8)+ip_header.source_address.address_2;

cout<<hex<<ip_word[7]<<endl;

ip_word[8]=(ip_header.source_address.address_3<<8)+ip_header.source_address.address_4;

cout<<hex<<ip_word[8]<<endl;

ip_word[9]=(ip_header.destination_address.address_1<<8)+ip_header.destination_address.address_2;

cout<<hex<<ip_word[9]<<endl;

ip_word[10]=(ip_header.destination_address.address_3<<8)+ip_header.destination_address.address_4;

cout<<hex<<ip_word[10]<<endl;

return 0;

}

В результате получим шестнадцатеричный код заголовка пакета:

4500 00c8 987e 0000 7f11 710f a3f2 cb32 c0a8 01ca.