Описание алгоритма фрагментации и сборки ip дейтаграмм.

Фрагментация и сборка производятся автоматически, не требуя от отправителя специальных действий. Каждая фрагментированная часть исходной дейтаграммы имеет тот же формат. Использование фрагментации повышает вероятность потери дейтаграммы, так как потеря даже одного фрагмента приводит к потере всей дейтаграммы. Сборка фрагментов дейтаграммы осуществляется на месте назначения. Такой метод позволяет маршрутизировать фрагменты независимо и требует промежуточной буферизации на маршрутизаторах. Поля в заголовке дейтаграммы — «Идентификатор», «Флаги» и «Смещение фрагмента» — управляют процессами фрагментации и сборки дейтаграммы.
Описание алгоритма подсчёта контрольной суммы ip заголовка.
Контрольная сумма заголовка (header checksum) рассчитывается только по байтам IP-заголовка. Она не включает в себя данные, расположенные вслед за ним. (Наоборот, заголовки ICMP, IGMP,UDP и TCP оснащены контрольной суммой, охватывающей как сам заголовок, так и их собственные данные.)
Для вычисления контрольной суммы IP-заголовка в исходящей дейтаграмме значение этого поля сначала устанавливается в 0. Затем выполняется сложение "по модулю один" всех 16-разрядных слов заголовка, и инвертированное значение результата записывается в поле контрольной суммы. При получении IP-дейтаграммы вновь вычисляется сумма 16-разрядных слов заголовка по модулю один. Так как в заголовке принятой дейтаграммы уже содержится сосчитанная (и инвертированная) отправителем контрольная сумма, в результате должно получиться слово, состоящее только из единиц (если в заголовке ничего не изменилось). Если же получилась другая комбинация (ошибка контрольной суммы), IP-модуль уничтожает дейтаграмму. Никакого сообщения об ошибке не порождается. Обнаружение потери дейтаграммы и повторная передача считаются проблемой, решаемой на вышестоящих уровнях иерархии протоколов.
Описание адресации в ip сетях.
IP-адрес состоит из двух частей. Первая часть IP-адреса обозначает адрес сети, последняя часть – адрес узла.
128.10.2.30 - традиционная десятичная форма представления адреса,
10000000 00001010 00000010 00011110 - двоичная форма представления этого же адреса.
Классификация IP адресов
Класс А
|
0 |
N сети |
N узла |
Класс В
|
1 |
0 |
N сети |
N узла |
Класс С
|
1 |
1 |
0 |
N сети |
N узла |
Класс D
|
1 |
1 |
1 |
0 |
адрес группы multicast |
Класс Е
|
1 |
1 |
1 |
1 |
0 |
зарезервирован |
-
Если адрес начинается с 0, то сеть относят к классу А, и номер сети занимает один байт, остальные 3 байта интерпретируются как номер узла в сети. Сети класса А имеют номера в диапазоне от 1 до 126. (Номер 0 не используется, а номер 127 зарезервирован для специальных целей, о чем будет сказано ниже.) В сетях класса А количество узлов должно быть больше 216, но не превышать 224.
-
Если первые два бита адреса равны 10, то сеть относится к классу В и является сетью средних размеров с числом узлов 28 - 216. В сетях класса В под адрес сети и под адрес узла отводится по 16 битов, то есть по 2 байта.
-
Если адрес начинается с последовательности 110, то это сеть класса С с числом узлов не больше 28. Под адрес сети отводится 24 бита, а под адрес узла - 8 битов.
-
Если адрес начинается с последовательности 1110, то он является адресом класса D и обозначает особый, групповой адрес - multicast. Если в пакете в качестве адреса назначения указан адрес класса D, то такой пакет должны получить все узлы, которым присвоен данный адрес.
-
Если адрес начинается с последовательности 11110, то это адрес класса Е, он зарезервирован для будущих применений.
Маска подсети
Расположив следующим образом IP-адрес и маску подсети, можно выделить составляющие сети и узла:
11000000.10101000.01111011.10000100 – IP-адрес (192.168.123.132)
11111111.11111111.11111111.00000000 – маска подсети (255.255.255.0)
Первые 24 разряда (число единиц в маске подсети) распознаются как адрес сети, а последние 8 разрядов (число оставшихся нолей в маске подсети) – адрес узла. Таким образом, получаем следующее:
11000000.10101000.01111011.00000000 – адрес сети (192.168.123.0)
00000000.00000000.00000000.10000100 – адрес узла (000.000.000.132)
Исходный код и результаты работы программы
Main.cpp
#include "buffer.h"
#include "IpAddress.h"
#include "IpDatagram.h"
#include <conio.h>
void const GetIpHeader(IpDatagram &head);
void GetIpData(IpDatagram &head);
void SetIpHeader(IpDatagram &head);
void TypeofService(byte TOS);
void Flags(byte flags);
void Protocol(byte protocol);
void Comparison(IpDatagram &head);
void main()
{
cout << "Hex Data Vector:\n";
shared_ptr <vector<byte>> v(new vector < byte >({
0x45, 0x00, 0x01, 0x43, 0x00, 0x14, 0x40, 0x00, 0x80, 0x06,
0x8f, 0xdf, 0x0a, 0x00, 0x02, 0x69, 0xd5, 0xdb, 0x87, 0x7d,
0xc0, 0x06, 0x0f, 0x42, 0x43, 0x51, 0xbb, 0x09, 0x00, 0x00,
0xfa, 0x02, 0x50, 0x18, 0xfa, 0xf0, 0x32, 0x2b, 0x00, 0x00 }));
for (unsigned int i = 0; i < v->size(); i++)
cout << hex << "0x" << (int)*(v->data() + i) << " ";
buffer buf(v);
try
{
buffer buf(v);
}
catch (exception &e)
{
cout << "Exception error";
}
IpDatagram IpHead(buf);
int ans = 0;
do {
cout << "\n\nWhat do you want to do?: \n";
cout << "1. Get Header;\n2. Set Header;\n3. Get Data;\n4. Wireshark vs. C++;\n0. Quit Programm.\n\n";
cout << "Your choice: ";
cin >> ans;
switch (ans)
{
case 1: GetIpHeader(IpHead); break;
case 2: SetIpHeader(IpHead); break;
case 3: GetIpData(IpHead); break;
case 4: Comparison(IpHead); break;
case 0: break;
}
} while (ans != 0);
}
void Protocol(byte protocol)
{
char name[][20] = { "Reserved", "ICMP", "Unassigned", "Gateway-to-Gateway", "CMCC",
"ST", "TCP", "UCL", "Unassigned", "Secure", "BBN RCC", "NVP", "PUP", "Pluribus", "Telnet" };
cout << name[protocol] << endl;
}
void Flags(byte flags)
{
char name1[][20] = { "Reserved: Not Set", "ERROR" };
char name2[][10] = { "Not Set", "Set" };
char name3[][10] = { "Not Set", "Set" };
int bits = ((flags >> 2) & 1);
cout << name1[bits] << endl;
bits = ((flags >> 1) & 1);
cout << "Don't Fragment: " << name2[bits] << endl;
bits = (flags & 1);
cout << "More Fragments: " << name3[bits] << endl;
}
void TypeofService(byte TOS)
{
char name1[][25] = { "Routine", "Priority", "Immediate", "Flash",
"Flash_Override", "CRITIC_ECP", "Internetwork_Control", "Network_Control" };
char name2[][20] = { "Normal Delay", "Low Delay" };
char name3[][20] = { "Normal Throughput", "High Throughput" };
char name4[][20] = { "Normal Reliability", "High Reliability" };
int service = (TOS >> 5);
cout << "Precedence: " << name1[service] << endl;
service = (TOS & 16) >> 4;
cout << "Delay: " << name2[service] << endl;
service = (TOS & 8) >> 3;
cout << "Throughput: " << name3[service] << endl;
service = (TOS & 4) >> 2;
cout << "Reliability: " << name4[service] << endl;
}
void const GetIpHeader(IpDatagram &head)
{
int ans = 0;
ipAddress src;
ipAddress dst;
start:
cout << "\nWhat header field do you want to see?: \n";
cout << "1. Version;\n2. IHL;\n3. Type of Service;\n4. Total Length;\n5. Identification;\n6. Flags;\n7. Fragment Offset;\n";
cout << "8. Time to Live;\n9. Protocol;\n10. Header Checksum;\n11. SourceIP;\n12. DestinationIP;\n0. Return to menu\n ";
do {
cout << "\nYour choice : ";
cin >> ans;
switch (ans) {
case 1: cout << "Version: " << endl << dec << (int)head.GetIpVersion() << endl;; break;
case 2: cout << "IHL: " << endl << dec << (int)head.GetIHL() << " bytes" << endl;; break;
case 3: cout << "ToS: "; TypeofService(head.GetToS()); break;
case 4: cout << "Total Length: " << endl << dec << (int)head.GetLength() << " bytes" << endl; break;
case 5: cout << "Identification: " << endl << hex << "0x" << (int)head.GetIdent() << endl; break;
case 6: cout << "Flags: \n"; Flags(head.GetFlags()); break;
case 7: cout << "Fragment Offset: " << endl << dec << (int)head.GetOffset() << endl; break;
case 8: cout << "Time to Live: " << endl << dec << (int)head.GetTTL() << endl; break;
case 9: cout << "Protocol: "; Protocol(head.GetProtocol()); break;
case 10: cout << "Checksum: " << endl << hex << "0x" << (int)head.GetChecksum() << endl; break;
case 11:
cout << "SourceIP: \n";
src = head.GetSourceIp();
src.out();
break;
case 12:
cout << "DestinationIP: \n";
dst = head.GetDestinIp();
dst.out();
break;
default: cout << "ERROR\n"; goto start;
case 0: break;
}
} while (ans != 0);
}
void SetIpHeader(IpDatagram &head)
{
int ans = 0;
start:
cout << "\n\nWhat header field do you want to set?: \n";
cout << "1. Version;\n2. IHL;\n3. Type of Service;\n4. Total Length;\n5. Identification;\n6. Flags;\n7. Fragment Offset;\n";
cout << "8. Time to Live;\n9. Protocol;\n10. Header Checksum;\n11. SourceIP;\n12. DestinationIP;\n0. Return to menu\n\n ";
do {
cout << "\nYour choice : ";
cin >> ans;
switch (ans) {
case 1:
{
int i = 0;
cout << endl << "Version - header's first 4 bits: enter the number [1..15] : ";
do {
cin >> i;
if (i <= 0 || i > 15)
cout << "\nERROR: Enter the number [1..15] : ";
} while (i <= 0 || i > 15);
head.SetIpVersion(i);
break;
}
case 2:
{
int i = 0;
cout << endl << "Header's Length [min = 20 bytes] - header's second 4 bits: enter the number [5..15] : ";
do {
cin >> i;
if (i < 5 || i > 15)
cout << "\nERROR: Enter the number [5..15] : ";
} while (i < 5 || i > 15);
head.SetIHL(i);
break;
}
case 3:
{
uint16_t i = 0;
cout << endl << "Type of Service - 2nd byte: enter the number [0..255] : ";
do {
cin >> i;
if (i < 0 || i > 255)
cout << "\nERROR: Enter the number [0..255] : ";
} while (i < 0 || i > 255);
head.SetToS(i);
break;
}
case 4:
{
uint16_t i = 0;
cout << endl << "Total Length [min = 20 bytes] - header's bytes 3 & 4: enter the number [20..65 535] : ";
do {
cin >> i;
if (i < 20 || i > 65535)
cout << "\nERROR: Enter the number [20..65 535] : ";
} while (i < 20 || i > 65535);
head.SetLength(i);
break;
}
case 5:
{
uint16_t i = 0;
cout << endl << "Identification - header's bytes 5 & 6: enter the number [1..65 535] : ";
do {
cin >> i;
if (i <= 0 || i > 65535)
cout << "\nERROR: Enter the number [1..65535] : ";
} while (i <= 0 || i > 65535);
head.SetIdent(i);
break;
}
case 6:
{
int i = 0;
cout << endl << "Flags - 3 bits: enter the number [0..7] : ";
do {
cin >> i;
if (i < 0 || i > 7)
cout << "\nERROR: Enter the number [0..7] : ";
} while (i < 0 || i > 7);
head.SetFlags(i);
break;
}
case 7:
{
uint16_t i = 0;
cout << endl << "Offset - 13 bits: enter the number [0..8191] : "; //8191 = 00011111 11111111
do {
cin >> i;
if (i < 0 || i > 8191)
cout << "\nERROR: Enter the number [0..8191] : ";
} while (i < 0 || i > 8191);
head.SetOffset(i);
break;
}
case 8:
{
uint16_t i = 0;
cout << endl << "Time to Live - 9th byte: enter the number [0..255] : ";
do {
cin >> i;
if (i < 0 || i > 255)
cout << "\nERROR: Enter the number [0..255] : ";
} while (i < 0 || i > 255);
head.SetTTL(i);
break;
}
case 9:
{
int i = 0;
cout << endl << "Protocol - 10th byte: enter the number [0..14] : ";
do {
cin >> i;
if (i < 0 || i > 14)
cout << "\nERROR: Enter the number [0..14] : ";
} while (i < 0 || i > 14);
head.SetProtocol(i);
break;
}
case 10:
{
uint16_t i = 0;
cout << endl << "Checksum - 11th & 12th bytes: enter the number [0..65 535] : ";
do {
cin >> i;
if (i < 0 || i > 65535)
cout << "\nERROR: Enter the number [0..65 535] : ";
} while (i < 0 || i > 65535);
head.SetChecksum(i);
break;
}
case 11:
{
uint16_t i = 0;
cout << endl << "Source IP - bytes 13, 14, 15, 16 - 4 numbers [0..255] : ";
for (int j = 0; j < 4; j++)
{
cout << "\nEnter the " << j + 1 << " number : ";
do {
cin >> i;
if (i < 0 || i > 255)
cout << "\nERROR: Enter the number [0..255] : ";
} while (i < 0 || i > 255);
}
head.SetSourceIP(i);
break;
}
case 12:
{
uint16_t i = 0;
cout << endl << "Destination IP - bytes 17, 18, 19, 20 - 4 numbers [0..255] : ";
for (int j = 0; j < 4; j++)
{
cout << "\nEnter the " << j + 1 << " number : ";
do {
cin >> i;
if (i < 0 || i > 255)
cout << "\nERROR: Enter the number [0..255] : ";
} while (i < 0 || i > 255);
}
head.SetDestinIP(i);
break;
}
default: cout << endl << "ERROR\n"; goto start;
case 0: break;
}
} while (ans != 0);
}
void GetIpData(IpDatagram &head)
{
cout << "\nIP Datagram's Data:\n";
buffer data = buffer(head.GetData(head), 20, head.GetData(head).GetLength());
for (int i = 0; i < head.GetData(head).GetLength(); i++)
cout << hex << (int)data[i];
cout << "\n\n";
}
void Comparison(IpDatagram &head)
{
ipAddress src;
ipAddress dst;
cout << "\t\tWireshark \tvs. \tC++";
cout << "\nVersion: \t4" << dec << "\t\t\t" << (int)head.GetIpVersion() << endl;;
cout << "IHL: \t\t20" << dec << "\t\t\t" << (int)head.GetIHL() << " bytes" << endl;;
cout << "ToS: \t\t0" << dec << "\t\t\t" << (int)head.GetToS() << endl;;
cout << "Total Length: 40" << dec << "\t\t\t" << (int)head.GetLength() << " bytes" << endl;
cout << "Identification: 0x15" << hex << "\t\t\t0x" << (int)head.GetIdent() << endl;
cout << "Flags: \t\t2" << hex << "\t\t\t" << (int)head.GetFlags() << endl;;
cout << "Fragment Offset:0" << dec << "\t\t\t" << (int)head.GetOffset() << endl;
cout << "Time to Live: 128" << dec << "\t\t\t" << (int)head.GetTTL() << endl;
cout << "Protocol: \tTCP\t\t\t"; Protocol(head.GetProtocol());
cout << "Checksum: \t0x90f9" << hex << "\t\t\t0x" << (int)head.GetChecksum() << endl;
cout << "SourceIP: \t10.0.2.105\t\t";
src = head.GetSourceIp();
src.out();
cout << "DestinationIP: \t213.219.135.125\t\t";
dst = head.GetDestinIp();
dst.out();
}
Buffer.h
#include <memory>
#include <iostream>
#include <vector>
#include <conio.h>
#include <stdlib.h>
#include <exception>
using namespace std;
typedef uint8_t byte;
/*Класс "Буфер", содержит индекс начала буфера внутри вектора,
длину буфера, умный указатель на вектор.*/
class buffer {
uint32_t m_start;
uint32_t m_length;
shared_ptr <vector<byte>> m_data;
public:
buffer();
buffer(shared_ptr <vector<byte>> data);
buffer(shared_ptr <vector<byte>> data, uint32_t start, uint32_t length);
buffer(buffer b, uint32_t start, uint32_t length);
byte& operator[](uint32_t index);
int const GetLength();
buffer operator=(buffer& b);
};
Buffer.cpp
#include "buffer.h";
#include <exception>
buffer::buffer()
{
m_start = 0;
m_length = 0;
m_data = 0;
}
buffer::buffer(shared_ptr <vector<byte>> data)
{
//len
if (data == nullptr) throw exception("Error");
m_data = data;
m_start = 0;
m_length = data->size();
}
buffer::buffer(shared_ptr <vector<byte>> data, uint32_t start, uint32_t length)
{
m_data = data;
m_start = start;
m_length = length;
}
buffer::buffer(buffer b, uint32_t start, uint32_t length)
{
//start and len
m_data = b.m_data;
m_start = start;
m_length = length;
}
byte& buffer::operator[](uint32_t index) { return *(m_data->data() + index + m_start); }
int const buffer::GetLength() { return m_length; }
buffer buffer::operator=(buffer& b)
{
m_data = b.m_data;
m_start = b.m_start;
m_length = b.m_length;
return *this;
}
ipAddress.h
#include <memory>
#include <iostream>
#include <vector>
#include <conio.h>
#include <stdlib.h>
using namespace std;
typedef uint8_t byte;
/*Класс IP Address, элементы - 4 байта ip адреса,
источника или получателя.*/
class ipAddress {
byte first;
byte second;
byte third;
byte forth;
public:
ipAddress();
ipAddress(byte a, byte b, byte c, byte d);
void out();
};
ipAddress.cpp
#include "IpAddress.h";
ipAddress::ipAddress() { first = second = third = forth = 0; }
ipAddress::ipAddress(byte a, byte b, byte c, byte d)
{
first = a;
second = b;
third = c;
forth = d;
}
void ipAddress::out()
{
cout << dec << (int)first << '.' << (int)second << '.'
<< (int)third << '.' << (int)forth << endl;
}
ipDatagram.h
#include <memory>
#include <iostream>
#include <vector>
#include <conio.h>
#include <stdlib.h>
using namespace std;
typedef uint8_t byte;
/*Класс дэйтаграммы, элементы - 3 разных буфера,
указывающие на один вектор, но на разные его части.*/
class IpDatagram {
buffer data;
buffer header;
buffer option;
public:
IpDatagram(buffer a);
byte const GetIpVersion();
byte const GetIHL();
byte const GetToS();
uint16_t const GetLength();
uint16_t const GetIdent();
byte const GetFlags();
uint16_t const GetOffset();
byte const GetTTL();
byte const GetProtocol();
uint16_t const GetChecksum();
ipAddress& const GetSourceIp();
ipAddress& const GetDestinIp();
void SetIpVersion(int i);
void SetIHL(int i);
void SetToS(uint16_t i);
void SetLength(uint16_t i);
void SetIdent(uint16_t i);
void SetFlags(int i);
void SetOffset(uint16_t i);
void SetTTL(uint16_t i);
void SetProtocol(int i);
void SetChecksum(uint16_t i);
void SetSourceIP(uint16_t i);
void SetDestinIP(uint16_t i);
buffer IpDatagram::GetData(IpDatagram &head);
};
ipDatagram.cpp
#include "buffer.h"
#include "IpAddress.h"
#include "IpDatagram.h"
IpDatagram::IpDatagram(buffer a)
{
auto len = a[0] & 0x0F;
len *= 4;
auto optionLen = len - 20;
auto totalLen = (a[2] * 0x100) + a[3];
header = buffer(a, 0, 20);
option = buffer(a, 20, optionLen);
data = buffer(a, len, totalLen - len);
}
byte const IpDatagram::GetIpVersion() { return header[0] >> 4; }
byte const IpDatagram::GetIHL() { return (header[0] & 15) * 4; } //15 = 00001111
byte const IpDatagram::GetToS() { return header[1]; }
uint16_t const IpDatagram::GetLength() { return (header[2] * 0x100) + header[3]; }
uint16_t const IpDatagram::GetIdent() { return (header[4] * 0x100) + header[5]; }
byte const IpDatagram::GetFlags() { return (header[6] & 0xe0) >> 5; } // e0 = 11100000
uint16_t const IpDatagram::GetOffset() { uint16_t temp = (header[6] * 0x100) + header[7]; return (temp & 0x1fff); }
byte const IpDatagram::GetTTL() { return header[8]; }
byte const IpDatagram::GetProtocol() { return header[9]; }
uint16_t const IpDatagram::GetChecksum() { return (header[10] * 0x100) + header[11]; }
ipAddress& const IpDatagram::GetSourceIp()
{
ipAddress Source(header[12], header[13], header[14], header[15]);
return Source;
}
ipAddress& const IpDatagram::GetDestinIp()
{
ipAddress Destination(header[16], header[17], header[18], header[19]);
return Destination;
}
void IpDatagram::SetIpVersion(int i)
{
header[0] = header[0] & 15;
header[0] = header[0] | (i << 4);
}
void IpDatagram::SetIHL(int i)
{
header[0] = header[0] & (15 << 4);
header[0] = header[0] | i;
}
void IpDatagram::SetToS(uint16_t i)
{
header[1] = i;
}
void IpDatagram::SetLength(uint16_t i)
{
if (i < GetIHL())
cout << "\nHeader's length (" << (int)GetIHL() << ") is bigger then Total Length! Enter the number : ";
header[2] = header[2] & 0;
header[2] = header[2] | (i >> 8);
header[3] = header[3] & 0;
header[3] = header[3] | (i & 255); //255 = 00000000 11111111
}
void IpDatagram::SetIdent(uint16_t i)
{
header[4] = header[4] & 0;
header[4] = header[4] | (i >> 8);
header[5] = header[5] & 0;
header[5] = header[5] | (i & 255);
}
void IpDatagram::SetFlags(int i)
{
header[6] = header[6] & 31; //31 = 00011111
header[6] = header[6] | (i << 5);
}
void IpDatagram::SetOffset(uint16_t i)
{
header[6] = header[6] & 224;
header[6] = header[6] | (i >> 8);
header[7] = header[7] & 0;
header[7] = header[7] | (i & 255);
}
void IpDatagram::SetTTL(uint16_t i)
{
header[8] = i;
}
void IpDatagram::SetProtocol(int i)
{
header[9] = i;
}
void IpDatagram::SetChecksum(uint16_t i)
{
header[10] = header[10] & 0;
header[10] = header[10] | (i >> 8);
header[11] = header[11] & 0;
header[11] = header[11] | (i & 255);
}
void IpDatagram::SetSourceIP(uint16_t i)
{
for (int j = 0; j < 4; j++)
{
header[12 + j] = i;
}
}
void IpDatagram::SetDestinIP(uint16_t i)
{
for (int j = 0; j < 4; j++)
{
header[16 + j] = i;
}
}
buffer IpDatagram::GetData(IpDatagram &head) { return data; }

Выводы
Изучил принцип работы протокола IPv4, структуру IP-датаграмы.
Контрольные вопросы:
-
Назначение протокола IP.
Протокол IP обеспечивает передачу блоков данных, называемых дейтаграммами, от отправителя к получателям, где отправители и получатели являются компьютерами, идентифицируемыми адресами фиксированной длины (IP-адресами). Протокол IP обеспечивает при необходимости также фрагментацию и сборку дейтаграмм для передачи данных через сети с малым размером пакетов”. Протокол IP является ненадежным протоколом без установления соединения. Это означает, что протокол IP не подтверждает доставку данных, не контролирует целостность полученных данных.
-
Какова минимальная длина заголовка IP дейтаграммы в байтах?
Корректный заголовок может иметь минимальный размер 5 32-битных слов, т.е. 20 байт.
-
Какова максимальная длина IP дейтаграммы в байтах?
Максимальный размер дейтаграммы может составлять 65535 байтов. В подавляющем большинстве сетей столь большой размер дейтаграмм не используется. По стандарту все устройства в сети должны быть готовы принимать дейтаграммы длиной до 576 байтов.
-
Каким образом определить начало данных в IP дейтаграмме?
Данные начинаются сразу после заголовка и опций (если есть). Зная длину заголовка, можно определить начало данных.
-
Каким образом определить размер данных в IP дейтаграмме?
В заголовке IP – дейтаграммы есть поля, значения которых содержат размер всей дейтаграммы и размер заголовка отдельно. Если из значения первого вычесть значение второго, можно узнать размер данных в дейтаграмме.
-
Что такое MTU? Как формируется это значение?
MTU означает максимальный размер полезного блока данных одного пакета, который может быть передан протоколом без фрагментации. Обычно заголовки протокола не входят в MTU, но в некоторых системах в некоторых протоколах заголовки могут учитываться. MTU задается в соответствии с протоколом (максимально возможный размер данных + размер заголовка).
-
Какова реальная длина IP дейтаграммы в сетях Ethernet?
В Ethernet максимальная длина кадра составлет 1500 байтов.
-
Перечислите классы IP-адресов. Укажите длину адреса сети и адреса хоста для каждого класса.
Для обеспечения гибкости в присвоении адресов компьютерным сетям разработчики определили, что адресное пространство протокола IP должно быть разделено на три основных различных класса — А, В и С. Каждый из этих основных классов фиксирует границу между сетевым префиксом и номером хоста в различных точках 32-разрядного адресного пространства.
|
Класс |
Адрес сети |
Адрес хоста |
|
A |
7 бит |
24 бит |
|
B |
14 бит |
16 бит |
|
С |
21 бит |
8 бит |
