ИП_Л_8 Лекция № 8. Простые сокеты 1. Протокол ICMP. 2. Сообщения об ошибках ICMP. 3. Сообщения-запросы ICMP. Вы знаете, что для доставки пакетов данных в Интернет используется ненадежный, однако эффективный протокол IP. IP не гарантирует доставку сетевых пакетов и не гарантирует уведомления в случае повреждения каналов связи или пакетов. Однако в некоторых случаях программное обеспечение TCP/IP все-таки вырабатывает сообщения о сетевых ошибках. В этой главе мы подробнее рассмотрим сообщения об ошибках, условия, при которых они возникают, и доставляющий сообщения протокол — протокол управляющих сообщений Интернет (Internet Control Message Protocol, ICMP). Вы узнаете, как при помощи Winsock API программа может генерировать сообщения ICMP. Для этого используется так называемый простой (raw) сокет. Как мы уже говорили, простой сокет обеспечивает доступ к протоколам низкого уровня, например ICMP. Прочитав эту главу, вы будете знать: ♦ Как структура сети TCP/IP ограничивает возможности передачи сообщений об ошибках. ♦ Какие виды ошибок ICMP находит и как их обрабатывает. ♦ Как можно интерпретировать сообщения ICMP. ♦ Как создается простой сокет и как через него передаются и принимаются данные. Существуют два варианта WINSOCK.DLL. Один обеспечивает работу с простыми сокетами, а другой — нет. (Дело в том, что спецификация Winsock версии 1.1 не обязывает включать обработку простых сокетов в WINSOCK.DLL.) Поэтому программа, в которой используются простые сокеты, будет работать не на каждой локальной сети. В этой главе мы покажем, как возможность того или иного WINSOCK.DLL обслуживать простые сокеты распознается программным путем. Примечание: Программа Trumpet WINSOCK.DLL, на прилагаемой к книге дискете, умеет работать с простыми сокетами. Это значит, что даже если ваша локальная сеть и не поддерживает простые сокеты, вы все равно можете разрабатывать программы на их основе. 1. Протокол ICMP Что такое ICMP? Протокол управляющих сообщений Интернет, ICMP, предназначен для обработки сетевых ошибок и других ситуаций, требующих вмешательства сетевых программ. В тех редких случаях, когда программа обращается к сетевому уровню, минуя протоколы транспортного уровня TCP или UDP, скорее всего ей нужен ICMP. Протокол ICMP описан в RFC 792 (Internet Control Message Protocol, Postel, 1981). Для того чтобы обратиться к протоколу низкого уровня, в частности, к ICMP, программе нужен простой сокет. Необходимо понимать, что создание простого сокета — нетривиальная задача, требующая от программиста значительных усилий. Так, например, для работы с ICMP на простом сокете вы будете должны самостоятельно заполнять структуры данных заголовков ICMP. Общая картина Сетевой уровень TCP/IP состоит из модуля IP и двух других модулей: ICMP и протокола групповых сообщений Интернет (IGMP). Для доставки данных ICMP, так же, как TCP и UDP, пользуется протоколом IP. На рис. 14.1 показано положение ICMP в стеке TCP/IP. Так же, как и IP, ICMP является частью сетевого уровня. Однако по отношению к IP ICMP все-таки протокол более высокого уровня. Другими словами, он доставляет собственные сообщения при помощи IP, точно так же, как это делают TCP или UDP. Вы знае1 ИП_Л_8 те, что доставка сообщений IP происходит в среде сетей с переключением пакетов, через мосты и маршрутизаторы. В большинстве случаев сеть работает надежно, поэтому у самого IP нет никаких методов, чтобы уведомить пакетный переключатель или маршрутизатор об ошибке при доставке пакета (что сделало протокол IP гораздо проще в реализации). ICMP добавляет эти методы к арсеналу TCP/IP. Как мы уже говорили, если прикладная программа не пользуется надежным протоколом, она и не должна рассчитывать Рис. 14.1. Сетевой уровень TCP/IP с модулями IP, ICMP и IGMP на получение каких-либо уведомлений об ошибках при доставке данных. Конструкция стека протоколов TCP/IP такова, что сообщения об ошибках видны только сетевому или транспортному уровням. Ошибки, о которых сообщается Если все сетевые компьютеры функционируют нормально и знают, как правильно маршрутизировать данные, сеть TCP/IP доставляет сообщения вполне эффективно. Разумеется, если в сети возникают проблемы, они в первую очередь влияют на доставку данных. Те или иные проблемы свойственны любой сети, не только на базе TCP/IP. Если неисправность местная, генерируется сообщение о неисправности аппаратуры, например. Для определения неисправности используются разнообразные приборы-анализаторы. Если неисправность удаленная, сначала необходимо выяснить, где она находится. Для этого исследуется структура сети, то есть совокупность маршрутизаторов, мостов и другой техники, установленной на пути к месту неисправности. В случае, если неисправность возникает где-то в объединении сетей, найти ее практически невозможно или крайне затруднительно. Назначение ICMP Изначально, ICMP проектировался как протокол, позволяющий маршрутизатору указать сетевому уровню передающего хоста на ошибку при доставке пакета. Сетевой уровень, в свою очередь, мог предпринять ответные действия. В последствии оказалось, что ICMP полезен не только маршрутизаторам. Им может воспользоваться любой сетевой компьютер для передачи сообщения об ошибке управляющего либо информационного сообщения другому сетевому компьютеру на локальной или глобальной сети. Сообщения ICMP инкапсулируются в IP-датаграммы. Пункт назначения сообщения ICMP — всегда сетевой уровень и никогда — определенный пользователь или сетевое приложение. Модуль ICMP IP-уровня компьютера-получателя определяет, передать ли сообщение протоколам высокого уровня, например транспортным или прикладным. Как вы увидите дальше, TCP/IP ограничивает сферу применения некоторых сообщений ICMP. Сообщения об ошибках ICMP ICMP обеспечивает только сообщения об ошибках. То есть в нем отсутствуют какие-либо функции по исправлению ошибочных данных. ICMP никак не определяет харак2 ИП_Л_8 тер действий сетевого уровня в ответ на те или иные ошибки. Свойственные ICMP ограничения Если при доставке пакета случается ошибка, ICMP доставляет сообщение только компьютеру-источнику. Как правило, это ограничение несущественно, поскольку ошибки возникают чаще всего из-за компьютера-источника сообщения. Однако поскольку ни один из промежуточных переключателей пакетов не получает ICMP-сообщения, то и компьютер-источник не всегда в состоянии исправить ошибку. Предположим, что неисправный переключатель пакетов неправильно маршрутизирует сообщение. По протоколу ICMP компьютер, принявший «неправильный» пакет, может доложить об этом только компьютеру-источнику. В результате, компьютер-источник оказывается не в состоянии определить, где именно случился сбой, и предпринять какие-либо ответные действия. Чтобы понять, почему протокол ICMP ограничен, давайте пристальнее рассмотрим дизайн семейства протоколов TCP/IP. А именно, давайте вспомним, что нам известно о маршрутизации IP-датаграмм. Заголовок IP-датаграммы содержит только адреса источника и приемника данных. Адреса в заголовке остаются неизменными на протяжении всего путешествия датаграммы по сети. Когда датаграмма попадает в переключатель пакетов, он исследует адрес назначения, сопоставляет его с имеющимися в таблице маршрутизации данными и отправляет по заданному маршруту, то есть к следующему переключателю пакетов. В конце концов, датаграмма доходит до переключателя пакетов, связанного напрямую с сетью или компьютером-получателем данных. В этом случае датаграмма отправляется прямо к компьютеру-получателю. В сетях TCP/IP маршрутизация происходит динамически, то есть таблицы обновляются и корректируются на ходу, и ни один отдельный маршрутизатор (переключатель пакетов) не знает всей таблицы маршрутизации объединения сетей. (Для упрощения протоколы маршрутизации TCP/IP сделаны невидимыми со стороны остальных протоколов семейства.) В результате, когда датаграмма доходит до получателя, ни она, ни получатель не имеют ни малейшего представления о пройденном маршруте. Также не существует метода, чтобы его выяснить. В результате, ICMP может доложить об ошибке доставки датаграммы только компьютеру-источнику данных. Для того чтобы ICMP обладал большими возможностями, понадобилось бы переделать все семейство TCP/IP. И все-таки, несмотря на ограничения, ICMP является достаточно мощным средством в ряду протоколов TCP/IP. Постановка задачи Для доставки своих данных ICMP пользуется услугами IP. В результате, приоритет сообщения ICMP и его надежность оказываются не выше, чем у любого другого пакета IP. Более того, ICMP сам может привести к некоторым проблемам при доставке данных. Например, если ICMP-сообщение возникает в результате столкновения сетевых данных, поток данных увеличивается, еще больше усугубляя ситуацию. Аналогично, если сообщение об ошибке ICMP умудряется само сгенерировать сообщение об ошибке, то оно, в свою очередь, может сгенерировать еще одно и т. д. Для того чтобы не возникало лишних сообщений об ошибках, пришлось разработать несколько важных правил. До того как вы познакомитесь с ними, необходимо познакомиться с двумя типами ICMP-сообщений: сообщением-запросом и сообщением об ошибке. Вы будете использовать сообщение-запрос ICMP для измерения величины задержки прохождения датаграммы между двумя компьютерами. Сообщения-запросы ICMP служат для переноса или запросов сетевой информации. Сообщение-запросы и сообщения об ошибках Как правило, сообщения об ошибках ICMP появляются в результате каких-либо проблем с доставкой сетевого сообщения. Таким образом, ICMP-сообщение тесно связано с IP-датаграммой — виновницей его появления. Сообщение об ошибке всегда содержит заголовок этой IP-датаграммы и первые 64 бита (восемь байт) ее данных. В отличие от сообщения об ошибке, сообщение-запрос не связано с ошибками доставки. Сообщениезапрос доставляет информацию относительно определенной сети или сетевого компьюте3 ИП_Л_8 ра. Сообщения-запросы ICMP используются для диагностических целей. Правила выдачи сообщений об ошибках ICMP В спецификации TCP/IP четко определены правила, руководствуясь которыми сетевой компьютер решает, может ли он передать ICMP-сообщение. Например, сообщениезапрос ICMP может привести к возникновению сообщения об ошибке. Чтобы сообщение об ошибке не привело к возникновению следующего сообщения и т. д., пока канал связи не исчерпает своей пропускной способности, сетевое программное обеспечение никогда не генерирует ICMP-сообщение об ошибке в ответ на другое ICMP-сообщение. Сообщение об ошибке никогда не генерируется в ответ на IP-датаграммы с широковещательным или групповым адресом. Такие адреса означают, что датаграмма направлена нескольким компьютерам, а их одновременная реакция на ICMP-сообщение может привести к полной перегрузке сети (broadcast storm). Чтобы лучше осознать последнее заявление, рассмотрим, что получится, если датаграмма с широковещательным адресом столкнется с проблемами при доставке и сгенерируется ICMP-сообщение об ошибке. Поскольку широковещательная датаграмма принимается всеми сетевыми компьютерами, IP-уровень каждого из них сгенерирует собственное ICMP-сообщение, и произойдет это одновременно. Ситуация лишь не намного улучшается, если адрес датаграммы не широковещательный, а групповой. Неопознанный адрес источника IP-датаграммы приведет к еще большим проблемам, поскольку ICMP-сообщения высылаются именно по его адресу. Если размер датаграммы слишком велик для физического уровня конкретной сетевой технологии, TCP/IP фрагментирует ее для пересылки по частям. Если фрагмент датаграммы по каким бы то ни было причинам повреждается или исчезает, ICMP отсылает сообщение об ошибке компьютеру-источнику. Поскольку компьютеру-источнику все равно потребуется повторить всю датаграмму целиком, ICMP-сообщение связывается только с первым поврежденным фрагментом. Такой подход также помогает справиться с проблемами перегрузки сети. Что такое ICMP-сообщение? Как мы уже говорили, ICMP передает сообщения-запросы и сообщения об ошибках. TCP/IP инкапсулирует ICMP-сообщение в IP-датаграмму. Сетевые программы распознают ICMP-соМщения по двум признакам: 8-битному значению Туре и 8-битному значению Code. Как показано на рис. 14.2, два этих значения являются первыми полями ICМРзаголовка. Рис. 14.2. Формат и инкапсуляция сообщения ICMP Сразу за двумя полями «Тип» (Туре) и «Код» (Code) следует 16-битное поле контрольной суммы. Как известно, контрольная сумма позволяет определить повреждение пакета на другом конце сетевого соединения. Позже в этой главе вы познакомитесь с исходным текстом процедуры на языке C/C++ для вычисления контрольной суммы. Контрольная сумма вычисляется не только для заголовка, но и для тела ICМР-сообщения. Дальнейшее содержимое заголовка зависит от типа сообщения. Так же как мы уже отмечали, ICMP-сообщение об ошибке содержит заголовок 1Р-датаграммы и первые 64 бита (восемь байт) ее данных. Кроме двух рассмотренных классов ICMP-сообщений су4 ИП_Л_8 ществует еще 15 типов. Они приведены в табл. 14.1. 2. Сообщения об ошибках ICMP Таблица 14.1. Типы сообщений ICMP Как видно из табл. 14.1, в ICMP определено множество различных типов сообщений, включая пять типов сообщений об ошибках. В следующих разделах мы по отдельности рассмотрим каждый тип сообщения об ошибках. Некоторые из этих типов являются подмножествами сообщений. Например, тип 3, «пункт назначение недоступен», имеет 16 различных видов «недоступности». Сообщения об ошибках «пункт назначения недоступен» Как мы уже говорили, изначально ICMP требовался для того, чтобы маршрутизатор мог сообщить о проблемах при доставке пакета. Если маршрутизатор не в состоянии направить пакет по нужному пути, он генерирует сообщение об ошибке типа 3 и посылает его компьютеру-источнику. Поскольку генерация такого рода сообщений была основной задачей ICMP, сообщения «пункт назначения недоступен» имеют наибольшее количество вариантов. Шестнадцать (0 — 15) кодов ошибок сообщения «пункт назначения недоступен» приведены в табл. 14.2. Таблица 14.2. Сообщения об ошибках ICMP типа пункт назначения недоступен 5 ИП_Л_8 Протокол IP не гарантирует доставку данных. С другой стороны, он почти всегда успешно справляется с доставкой. Если IP не удается доставить датаграмму, значит, возникла сетевая проблема, например ошибки при маршрутизации. Если вы внимательно изучили табл. 14.2, то наверное заметили, что большинство сообщений об ошибках относятся либо к компьютеру, либо к сети. Как правило, сообщения, относящиеся к компьютеру, означают проблему с доставкой, а сообщения, относящиеся к сети, — проблему с маршрутизацией. Так, например, код ошибки «сеть недоступна» означает проблему с маршрутизацией. На рис. 14.3 изображен формат ICMP-сообщения «пункт назначения недоступен». Формат сообщения подобен общему формату, изображенному на рис. 14.2. Тип сообщения в поле типа равен трем, а поле кода (Code) соответствует коду ошибки от 0 до 15. Кроме того, в ICMP-сообщении содержится заголовок 1Р-датаграммы, вызвавшей его появление, и первые 64 бита (восемь байт) ее данных. Рис. 14.3. Формат ICMP-сообщения «пункт назначения недоступен» Пункт назначения может быть недоступен, если IP-заголовок содержит неправильный адрес назначения, либо если какое-нибудь промежуточное сетевое устройство выключено, либо, что менее вероятно, в таблице маршрутизации отсутствует путь к сети назначения. Все маршрутизаторы обязаны сообщать о сбое при доставке пакета источнику этого пакета. К сожалению, сами эти сообщения могут теряться. Существующая вероят6 ИП_Л_8 ность потери сообщения об ошибке и делает протокол ICMP ненадежным. (Вы помните, что ICMP пользуется услугами ненадежного IP.) Сообщения об ошибках перенаправления Как вы знаете из четвертой главы, чтобы выяснить, по какому маршруту послать пакет, переключатели пакетов TCP/IP пользуются таблицами маршрутизации. Маршрутизация пакета основывается на номере сети назначения, а идентификатор сети назначения — это часть IP-адреса. Каждый маршрутизатор знает своего соседа, то есть следующую «остановку», которых может быть несколько, на пути пакета данных. В некоторых случаях к определенной сети могут вести несколько маршрутов. Для постоянного слежения за состоянием сети маршрутизаторы периодически обмениваются сообщениями. Тем не менее таблицы маршрутизации обновляются не очень часто. Исходные данные для них хранятся в местных файлах конфигурации — это минимально необходимая для начала работы маршрутизатора информация, как правило, адрес другого маршрутизатора или шлюза. Компьютеры обновляют свои таблицы, основываясь на информации от маршрутизаторов и сообщения о перенаправлении ICMP — один из способов решать эту задачу. Предположим, что ваш компьютер посылает датаграмму на компьютер коллеги, расположенный, как показано на рис. 14.4, в другой физической сети. Чтобы послать датаграмму, необходимо обратиться к маршрутизатору. Предположим, что датаграмма посылается маршрутизатору номер 2. Исследовав свою таблицу, маршрутизатор обнаружит, что компьютер коллеги находится на расстоянии одного «прыжка» от маршрутизатора номер 1 и что именно ему следует послать датаграмму. В результате, датаграмма отправляется к маршрутизатору номер 1. Рис. 14.4. Пример ICMP-сообщения о перенаправлении (тип 5) Кроме того, маршрутизатор номер 2 знает (из содержимого датаграммы и собственной таблицы), что ваш компьютер подсоединен к маршрутизатору номер 1 напрямую, а следовательно, датаграмму можно слать сразу ему — это будет оптимальный маршрут. Как только маршрутизатор определит, что существует лучший маршрут, он отправит ICMP-сообщение о перенаправлении компьютеру-источнику датаграммы. На рис. 14.5 показан формат сообщения о перенаправлении. Компьютер-передатчик выясняет, что следующие датаграммы лучше слать маршрутизатору, IP-адрес которого содержится в ICMP-сообщении. Другими словами, получив ICMP-сообщение о перенаправлении, ICMP-модуль компьютера должен исследовать содержимое заголовка IP-датаграммы (в теле сообщения) и IP-адрес маршрутизатора (второе 32-битное слово в заголовке сообщения). IP-заголовок даст адрес, по которому датаграммы шли неверным маршрутом, а 7 ИП_Л_8 Рис. 14.5. ICMP-сообщение о перенаправлении (тип 5) IP-адрес маршрутизатора — тот маршрутизатор, который нужно использовать теперь. Эта информация может потребоваться для обновления таблицы маршрутизации сетевого компьютера. В табл. 14.3 приведены четыре кода сообщений о перенаправлении (тип 5). В примере на рис. 14.4 маршрутизатор пошлет сообщение типа 5 с кодом 1 (перенаправление для хоста). Таблица 14.3. ICMP-сообщения об ошибках перенаправления (тип 5) Как видим, маршрутизатор может перенаправить сообщение, основываясь на содержимом поля «тип сетевой службы» (TOS) IP-заголовка датаграммы. Как вам известно из четвертой главы, поле TOS заголовка датаграммы определяет ее приоритет. Хотя это поле применяется редко, в будущем, несомненно, его значение возрастет. Поэтому в ICMP заложена возможность помогать сетевым компьютерам обновлять таблицы маршрутизации, в зависимости от типа сетевой службы, которой принадлежит та или иная датаграмма. Протокол ICMP ограничивает сферу применения сообщений о перенаправлении. Каждый сетевой компьютер, в принципе, может работать маршрутизатором. Однако только системы, сконфигурированные как маршрутизаторы, могут посылать ICMP-сообщения о перенаправлении. Обыкновенный сетевой компьютер сделать этого не может. Далее, маршрутизаторы не обновляют свои таблицы, основываясь на сообщениях о перенаправлении. Вместо этого маршрутизаторы используют специальные протоколы. Ошибки типа «лимит времени исчерпан» Как известно, ошибки в таблицах маршрутизации могут привести к зацикливанию пакета между двумя маршрутизаторами. Это может случиться, когда каждый из них считает, что соседний маршрутизатор — наилучшее место для передачи пакета по назначению. Заголовок IP-датаграммы содержит специальное поле «время существования» (Timeto-Live, TTL), в котором время существования датаграммы ограничивается. Каждый маршрутизатор на пути пакета уменьшает время его существования. Время существования также уменьшается каждую секунду, которую пакет проводит во входной или выходной очереди маршрутизатора. Как только время существования в поле TTL IP-датаграммы сравняется с нулем, сетевые программы уничтожат пакет и вышлют ICMP-сообщение «лимит времени исчерпан» (тип 11) компьютеру-источнику пакета. Формат ICМР-сообщения «лимит времени исчерпан» такой же, как у сообщения «пункт назначения недоступен», но поле Туре равно 11 вместо 3. Сообщения «лимит времени исчерпан» бывают двух видов, как показано в табл. 14.4. Код 0 устанавливается в случае, если датаграмма исчерпала время существования во время пересылки (например, из-за описанного выше зацикливания). Код 1 устанав8 ИП_Л_8 ливается, если произошел сброс таймера сборки фрагментов датаграммы до того, как все фрагменты прибыли. Таблица 14.4. ICМР-сообщения об ошибках «лимит времени исчерпан» (тип 11) Как вам известно из четвертой главы, когда компьютер-получатель принимает датаграмму с установленным флагом «фрагмент-продолжение», запускается таймер сборки фрагментов. Все фрагменты обязаны появиться до того, как этот таймер истечет. Если таймер истек, а датаграмма все еще не собрана, она уничтожается. В этом случае генерируется ICMP-сообщение типа 11с кодом 1. Ошибки «неверный параметр» Компьютеры и маршрутизаторы высылают такое сообщение, если источник проблемы с маршрутизацией или доставкой неизвестен. Существуют два типа таких ICMPсообщений, как показано в табл. 14.5. Таблица 14.5. ICMP-сообщение об ошибке «неверный параметр» (тип 12) Сообщение с кодом 1 генерируется, если датаграмма не содержит всех необходимых для нормальной работы TCP/IP атрибутов (опций). Предположим, вы разработали криптозащищенный протокол для работы с приложениями государственной важности. Если программа-клиент попытается передать запрос к серверу и не приложит специального секретного ключа к датаграмме, сервер ответит сообщением об ошибке типа «необходимая опция отсутствует». Сообщение типа «неверный IP-заголовок» генерируется во всех остальных случаях, когда источник ошибки невозможно распознать. На рис. 14.6 приведен формат сообщения ICMP «неверный параметр». Поле указателя (pointer) идентифицирует тот байт датаграммы, который привел к возникновению ICMP-сообщения. Для сообщений с кодом 1 («необходимая опция отсутствует») поле указателя равно нулю. Рис. 14.6. Формат ICMP-сообщения «неверный параметр» (тип 12) Сообщение об ошибке «столкновение данных» Как мы писали во второй главе, механизм контроля потока данных гарантирует, что передатчик не будет передавать быстрее, чем приемник в состоянии принять и обработать. Другими словами, гарантируется, что входной буфер приемника не переполнится. В главе 5 мы писали, что протокол TCP обеспечивает механизм управления потоком в качестве одной из сетевых служб. К сожалению, управление потоком возможно лишь тогда, когда протокол ориентирован на соединение. Поскольку IP не ориентирован на соединение, он не умеет управлять потоком данных. Поскольку маршрутизаторы работают на уровне IP, в их входных очередях может создаваться аналог транспортной пробки в часы пик в результате слишком большого количества вновь приходящих IP-пакетов. 9 ИП_Л_8 Если маршрутизатор не успевает обработать все приходящие пакеты, «лишние» пакеты уничтожаются, а компьютеру-источнику пакета направляется 1СМР-со-общение об ошибке «столкновение данных» (тип 4). Сообщение «столкновение данных» указывает компьютеру на необходимость снизить скорость передачи. На самом деле, механизм сообщений «столкновение данных» является некоторым подобием управления потоком данных на уровне IP. Для каждого уничтоженного в результате столкновения пакета, маршрутизатор высылает 1СМР-со-общение. Как только компьютер получает его, он тут же снижает скорость передачи. Если маршрутизатор продолжает передавать ICMP-сообщения «столкновение данных», компьютер продолжает снижать скорость передачи. Как только ICMP-сообщения перестают появляться, компьютер вновь начинает увеличивать скорость. И так до тех пор, пока не будет достигнута оптимальная скорость. Формат сообщения ICMP «столкновение данных» тот же, что и у сообщения «пункт назначения недоступен», только поле типа имеет значение 4. Сообщение «столкновение данных» бывает только единственного вида, то есть поле кода у него всегда имеет значение 0 — других кодов не бывает. 3. Сообщения-запросы ICMP Кроме сообщений об ошибках протокол ICMP генерирует сообщения-запросы, переносящие информацию относительно сетевой маршрутизации, производительности, адресов подсетей и т. д. Эта информация используется в отладочных целях. В следующих разделах мы рассмотрим каждый тип сообщений-запросов ICMP. Запросы «информация о маршрутизаторах» Информация о маршрутизации находится в местных конфигурационных файлах и загружается оттуда при запуске компьютера. Чтобы таблица маршрутизации не содержала устаревших данных, в дальнейшем она обновляется динамически. Протокол ICMP — один из способов динамического обновления таблиц. В ICMP существуют два типа сообщений маршрутизаторов: «информация о маршрутизации» (тип 10) и «регистрация маршрутизатора» (тип 9). Каждый раз, когда компьютер запускается, он генерирует сообщение о регистрации. В ответ маршрутизаторы-соседи генерируют сообщение с информацией о маршрутизации, позволяющее правильно сконфигурировать таблицу. Формат сообщений о маршрутизации описан в документе RFC 1256, «ICMPcoобщения о маршрутизации» (ICMP Router Discovery Messages, Deering, 1991). На рис 14.7 показы форматы обоих типов сообщения. Формат сообщения «регистрация маршрутизатора» весь похож на формат сообщения «пункт назначения недоступен», приведенный на рис. 14.3. Однако сообщение «регистрация маршрутизатора» не содержит данных IP-датаграммы в своем теле. Как показано на рис. 14.7, в одном ICMP-сообщении могут описываться несколько адресов. (Вы помните, что у одного компьютера может быть несколько сетевых интерфейсов и у каждого собственный IP-адрес.) Поле «количество адресов» в заголовке ICMPсообщения указывает принимающему компьютеру, сколько адресов перечислено в сообщении. Поле «размер адреса» задает длину каждого адреса в 32-битных словах. В настоящее время длина адреса всегда равна двум. Другими словами, длина адреса равна восьми байтам (32-разрядный адрес маршрутизатора и 32-разрядное поле уровня приоритета). Поле «время существования» задает время, в течение которого информация об адресах еще не устарела. Как правило, оно равно 30 минутам (1800 секунд). Одно сообщение «информация о маршрутизации» содержит одно или несколько полей адреса маршрутизатора и соответствующих полей уровня приоритета. IP-адрес, как вы помните, соответствует не сетевому компьютеру, а его интерфейсу, которых может быть несколько. Таким 10 ИП_Л_8 Рис. 14.7. Формат ICMP-сообщения с информацией о маршрутизации (тип 9 и тип 10) образом, несколько IP-адресов могут относиться к одному и тому же компьютеру. Уровень приоритета является 32-разрядным целым числом со знаком, указывающим компьютеру, какой из адресов следует использовать первым и интенсивнее. Чем больше значение приоритета, тем выше приоритет у соответствующего адреса. Маршрутизаторы передают информационные ICMP-сообщения широковещательно через случайные интервалы времени. Интервалы, как правило, колеблются от 450 до 600 секунд, а значение поля «время существования» по умолчанию равно 30 минутам. Поле «время существования» может использоваться для уведомления маршрутизаторов-соседей о том, что данный маршрутизатор выключается. Для этого маршрутизатор передает ICMPсообщение с полем «время существования», равным нулю. ICMP-запрос «регистрация маршрутизатора» передается, как правило, три раза с интервалом в три секунды при запуске маршрутизатора и продолжает передаваться до тех пор, пока хост не получит информационного ICMP-сообщения с необходимыми для обновления таблицы данными. Несмотря на то, что ICMP-сообщения о маршрутизации обеспечивают более надежный способ конфигурирования хостов по сравнению с традиционными, этот метод не очень широко применяется на практике. Запросы «временная метка» Запросы «временная метка» (типы 13 и 14) позволяют вычислить время прохождения пакета между двумя компьютерами. На рис. 14.8 изображен формат сообщений обоих типов. Рис. 14.8. Формат ICMP-сообщений «временная метка» (типы 13 и 14) Для того чтобы различать временные метки, используются два поля: идентификатор метки и номер последовательности. Компьютер-источник сообщения может запол11 ИП_Л_8 нять их наиболее удобным для себя образом. Сам протокол ICMP никак не анализирует содержимое этих полей. Три поля «временная метка» содержат количество секунд, прошедшее с полуночи. До того как послать датаграмму, компьютер заполняет первое поле значением текущего времени. Компьютер-приемник датаграммы заполняет поле «принятая временная метка», как только датаграмма доходит до него. Кроме того, компьютерприемник заполняет поле «переданная временная метка» перед тем, как послать ответную датаграмму. Как программист, вы должны понимать, что указанные в полях «временная метка» значения ненадежны, поскольку время перемещения отдельного пакета варьируется в широких пределах даже для сравнительно короткого интервала времени, поэтому действительное время прохождения пакетов абсолютно достоверно измерить невозможно. Даже если посылается множество пакетов, а затем вычисляется статистический результат, фактическая задержка распространения может сильно отличаться от него. Примечание: Большинство сетевых компьютеров устанавливают одинаковые значения для принятых и переданных временных меток. Сообщение-запрос маски адреса Как вы помните из четвертой главы, Информационный центр сети Интернет (InterNIC) выделяет номера сетей, а вопросами распределения номеров компьютеров занимаются сетевые администраторы. Сеть, находящаяся в распоряжении администратора, может быть разделена на несколько подсетей. Это позволяет эффективнее распределять адресное пространство. При этом адрес сети — это первая часть IP-адреса компьютера, а оставшаяся часть — номер компьютера в данной сети. Маска подсети определяет, на сколько частей (подсетей) разделена конкретная IP-сеть. Как вы помните, протокол RARP (обратного преобразования адресов) позволяет по адресу физического уровня выяснить IP-адрес компьютера. Им пользуются бездисковые станции, чтобы найти собственный IPадрес в процессе загрузки. Как только бездисковая станция получает ответ на свой RARPзапрос, она может передать запрос по IP-адресу нужного хоста с тем, чтобы загрузить свою операционную систему. Чтобы получить маску своей подсети, бездисковая станция передает ICMP-запрос. Чтобы выполнить эту задачу, бездисковая станция должна знать, какая часть ее 32-разрядного IP-адреса является номером подсети, а какая — номером компьютера. На рис. 14.9 показан формат ICMP-сообщений на определение и получение маски подсети. Рис. 14.9. Формат ICMP-сообщений запроса и ответа на получение маски адреса (типы 17 и 18) Поля идентификатора и номера последовательности такие же, как и в сообщении «временная метка». Другими словами, компьютер-передатчик может заполнять их, как ему удобнее. Сообщение-ответ ICMP содержит маску подсети, на которой находится компьютер-источник сообщения. Бездисковая станция не обязана знать адрес компьютера, ответственного за генерацию ответа, — она может просто воспользоваться широковещательной передачей. При этом ей ответит один или несколько компьютеров. Запрос и ответ «эхо» ICMP-сообщения «эхо» — образец диагностического инструмента, встроенного в сетевой протокол. Когда ICMP-модуль компьютера получает запрос «эхо», он высылает идентичное сообщение-ответ «эхо» передававшему компьютеру. Ответное сообщение «эхо» говорит о том, что пославший его компьютер пребывает в рабочем состоянии и способен отвечать на сетевые запросы. Сообщения-запросы и ответы «эхо» — одни из самых популярных сообщений 12 ИП_Л_8 ICMP, которые используются такими программами, как Ping (Packet INternet Grouper). Как правило, программа Ping высылает сообщения-запросы «эхо», получает ответы и измеряет среднее время движения пакетов по сети. Она используется для того, чтобы выяснить, работает ли в данный момент определенный сетевой компьютер и доступен ли он по сети. На рис. 14.10 приведен формат сообщений-ответов и запросов «эхо». Чтобы привязать запрос к ответу, используются поля идентификатора и номера последовательности. Так же, как и в сообщениях временной метки и маски адреса, туда может помещаться любая приемлемая для компьютера информация. Компьютер-передатчик сообщения также может разместить информацию в поле Рис. 14.10. Формат сообщений-запросов и ответов ICMP «эхо» дополнительных данных. Компьютер-получатель работает, как простой повторитель сообщений «эхо» — он отсылает обратно все принятые ICMP-сообщения. 4. Алгоритм использования простых сокетов Простые сокеты Теперь, когда вы узнали больше о протоколе ICMP, мы приступим к изучению простых сокетов. Простой сокет — это средство, позволяющее прикладной программе обойти стандартный транспортный уровень, с тем чтобы работать непосредственно с низкоуровневыми протоколами, например ICMP. Работа с простым сокетом происходит следующим образом. Во-первых, простой сокет создается. Вместо атрибутов сокета SOCK_STREAM или SOCKDGRAM указывается атрибут SOCK_RAW. Кроме того, программа должна указать используемый с сокетом протокол, например ICMP. После этого реализация Winsock добавляет IP-заголовок к данным, передаваемым через простой сокет. В поле «протокол» IP-заголовка указывается номер протокола, с которым вы работаете, заданного при создании сокета. Как только Winsock получает данные для указанного протокола, они передаются (вместе с IP-заголовком) процессу, создавшему сокет для этого протокола. Если ваша программа создала ICMP-сокет, она получит все ICMP-сообщения, адресованные данному сетевому компьютеру. Прикладная программа должна исследовать содержимое ICMPсообщений, чтобы определить, кому именно они предназначены. Как правило, такого рода операциями занимается транспортный уровень, но в данном случае он недоступен. Вновь поступающие данные не могут связываться с определенным сокетом или номером протокола автоматически. В следующих разделах мы покажем, как создавать и пользоваться простым сокетом. Также вы узнаете, как вычисляются контрольные суммы. В заключение вы встроите разработанный код в программу Sockman. Учебная программа Ping Учебная программа Ping (QPing) представляет собой упрощенный аналог общеизвестной программы Ping, широко используемой в Интернет. Как и у всех остальных учебных программ, значения параметров в ней жестко заданы. В результате, мы получаем полнофункциональную программу, демонстрирующую приемы программирования Интернет и не отягощенную излишними, характерными для программирования в Windows деталями. Ниже приведен исходный текст программы QPing. Для начала обратите внимание на три ее основных функции: InternetChksum, DoPingOperation и WinMain. Функции InternetChk-sum и DoPingOperation описаны словами, а функция WinMain определена полностью: 13 ИП_Л_8 14 ИП_Л_8 Первым делом WinMain вызывает WSAStartup для инициализации WINSOCK.DLL. Далее, вызывается функция DoPingOperation, которая посылает и затем принимает ICMPдатаграмму. По окончании работы функции DoPingOperation управление опять передается функции WinMain, которая выводит текстовое сообщение на экран с результатами операции, записанными в глобальной переменной szPingBuffer. После этого программа заканчивается. QPing определяет символьные константы и декларирует описания структур данных для IP-заголовка и сообщений ICMP. Как и в предыдущих учебных программах, константа PROG_NAME задает название рабочего проекта. Константа HOST_NAME определяет имя любого доступного сетевого компьютера. Константы WINSOCKVERSION и NO_FLAGS такие же, как и в предыдущих учебных примерах. WONSOCK_VERSION определяет минимальную необходимую для работы версию реализации WINSOCK.DLL, a NO_FLAGS — то, что при вызовах функций Winsock никаких дополнительных флагов не задается. Константы ICMP_ECHO, ICMP_ECHOREPLY и ICMP_HEADERSIZE новые, однако их значения вам знакомы из предыдущих разделов этой главы. Всем трем константам присваиваются значения из RFC 792. (Как мы уже говорили, в документе RFC 792 описан протокол ICMP.) Константа 1СМР_ЕСНО определяет содержимое поля типа сообщениязапроса «эхо». Константа ICMPEC-HOREPLY определяет содержимое поля типа сообщения-ответа «эхо». Константа ICMP_HEADERSIZE задает размер ICMP-заголовка для сообщений типа «эхо» и равняется восьми байтам, как показано на рис. 14.10: Структуры данных QPing В двух новых структурах данных, ip и icmp, определены заголовки пакетов IP и ICMP. Имена полей структуры ip в точности повторяют имена полей заголовка IPдатаграммы, изученные вами в четвертой главе. Точно так же имена полей структуры 15 ИП_Л_8 icmp в точности соответствуют именам полей заголовка ICMP-пакета, известного вам по настоящей главе. Длины элементов структур и длины соответствующих полей также в точности совпадают. Ниже приведено описание структур ip и icmp: Чтобы создать простой сокет, требуется гораздо больше усилий, чем при создании обыкновенного стандартного сокета. Для начала вы должны определить все нужные структуры данных и заполнить их правильными значениями. Для этого требуется понимать структуру данных низлежащего сетевого протокола и общую структуру пакета. Если значения полей пакета будут неверными или длины полей пакета будут ошибочными, программа просто не заработает. С другой стороны, если вы знаете, как функционирует протокол и какие данные ему нужны для работы, создание простого сокета не будет слишком сложной задачей. Очевидно, что для создания простого сокета, требуется написать больше исходного текста, чем в обычном случае. Это не сложнее, чем описать стандартный сокет, однако следует уделять больше внимания различным мелким деталям. Другими словами, следует проверять, все ли структуры данных соответствуют спецификации протокола и все ли поля содержат правильные значения. Вычисление контрольной суммы Для обнаружения поврежденных пакетов сетевые программы пользуются контрольными суммами и CRC. Вкратце, процесс создания контрольной суммы заключается в складывании двоичных значений каждого символа пакета и помещении результата в отдельный блок, передаваемый с тем же пакетом. Для проверки целостности данных компьютер-получатель также вычисляет значение контрольной суммы и сверяет его с принятым старым значением. Если контрольная сумма не совпадает, данные были повреждены. До того как рассмотреть функцию DoPingOperation, давайте познакомимся с функцией InternetChksum для вычисления контрольной суммы ICMP-датаграммы. Алгоритм ее работы достаточно прост. Данные компонуются в ряд 16-битных значений, затем значения складываются и вычисляется дополнение до единицы полученной суммы. Полученная контрольная сумма заносится в соответствующее поле структуры данных протокола. Ни16 ИП_Л_8 же приведен исходный текст функции для вычисления контрольных сумм. Функция используется как в программе QPing, так и в утилите Ping программы Sockman: Принципы вычисления контрольной суммы подробно описаны в документе RFC 1071, «Вычисление контрольной суммы Интернет» (Computing the Internet Checksum, Braden, Borman, Partridge, 1988). Там, в частности, указано, что эффективность алгоритма является ключевым моментом в обеспечении высокой производительности сети. Это значит, что алгоритм должен привязываться к аппаратным особенностям конкретной сетевой среды. Лишь в этом случае удается «вытянуть» из производительности компьютера все что только можно. Например, переменные lSum и wAnswer можно было бы (правда, не в нашем примере) объявить регистровыми (тип register). Регистровые переменные хранятся не в основной памяти компьютера, а в аппаратных регистрах процессора, увеличивая скорость выполнения функции. В любом случае, если вы планируете работать с простыми сокетами, найдите время для изучения RFC 1071 и дополнительной документации, перечисленной там. Освойте сначала общие принципы вычисления контрольных сумм, а затем рекомендации по тонкой настройке таких алгоритмов. Процедура Ping Функция DoPingOperation посылает эхо-запрос ICMP, а затем ждет эхо-ответа. В ней больше операторов, чем в предыдущих функциях. Правда, большинство из них являются объявлениями переменных, операторами присваивания и другими не относящимися к делу операторами. Если из кода удалить проверку ошибок и оставить только вызовы функций Winsock, мы получим следующую картину: 17 ИП_Л_8 Как видим, в функции очень немного незнакомых вам операторов. На самом деле здесь всего три новых для вас функции: getprotobyname, sendto и recvfrom. В вызове getprotobyname всего лишь один параметр — указатель на имя протокола. Первым делом она извлекает информацию об указанном протоколе из сетевой базы данных (файла на диске), а затем возвращает указатель на структуру данных, описывающую этот протокол: 18 ИП_Л_8 Элемент p_name указывает официальное имя протокола, а элемент p_aliases — список псевдонимов имен данного протокола, оканчивающийся NULL. В программе О Ping используется только элемент p_proto; в нем содержится номер протокола (в компьютерном порядке следования байтов). В предыдущих учебных программах мы использовали протокол TCP на ориентированных на соединение сокетах. Для обмена данными служили функции recv и send. Простой сокет работает с не ориентированными на соединение протоколами, чьи данные переносятся в датаграммах, поэтому для обмена данными используются функции recvfrom и sendto. Разница между двумя парами функций состоит в том, что в последней мы имеем возможность задавать адрес назначения, a send и recv работают только с предварительно соединенным сокетом. Вот прототип функции sendto: int PASCAL FAR sendto(SOCKET s,const char FAR * buf, int len, int flags, const struct sockaddr FAR * to, int tolen ); Первый параметр идентифицирует сокет. Второй параметр указывает на буфер с данными для передачи, размер которого задается третьим параметром. В качестве четвертого параметра могут использоваться два ранее описанных для функции send флага: MSG_DONTROUTE и MSG_OOB. Если вы хотите запретить маршрутизацию данных, вы должны указать флаг MSG_DONTROUTE. Если вы хотите послать данные «вне диапазона» (для немедленной обработки), указывайте флаг MSG_OOB. В большинстве учебных программ этой книги флаги не используются. Пятый параметр функции sendto указывает на структуру адреса сокета. В ней хранится адрес назначения ваших данных. Последний параметр sendto задает длину этой структуры. Прототип функции recvfrom, приведенный ниже, весьма похож на прототип sendto: Основное отличие двух прототипов в том, что пятый и шестой параметры последнего задавать необязательно. Если параметр from функции recvfrom не равен нулю, Winsock копирует адрес удаленного процесса, приславшего данные, в структуру адреса сокета, указанную параметром. То есть если программа желает знать адреса всех приславших данные для этого сокета компьютеров, необходимо отвести область памяти (буфер) для хранения структуры адреса сокета. Кроме того, длина этого буфера будет копироваться в переменную по указателю fromlen. Если программе не нужны адреса удаленных компьютеров, пятый параметр функции recvfrom должен равняться нулю. Еще одна незнакомая вам функция Windows — GetTickCount. Она возвращает время (в миллисекундах), прошедшее с момента запуска Windows. В QPing это значение используется для подсчета среднего времени пробега ICMP-датаграм-мы «эхо» между двумя компьютерами. Ниже приводится полный исходный текст функции DoPingOperation. 19 ИП_Л_8 20 ИП_Л_8 21 ИП_Л_8 22 ИП_Л_8 23 ИП_Л_8 Добавляем утилиту Ping в программу Sockman Исходный текст программы Sockman5, включающий исходный текст утилиты Ping, находится на приложенной к книге дискете. В Sockman5 используется такое же, как и в Sockman4, диалоговое окно. Для того чтобы встроить Ping в Sockman, файл PING5.CPP необходимо включить в список проекта или файл makefile вашего компилятора. Файлу PING5.CPP необходим файл-заголовок SOCKRAW.H, в котором описаны заголовки протоколов IP и ICMP. В утилите Ping используются только синхронные (блокирующие) функции — никаких асинхронных, специфических для Windows функций. Чтобы пользоваться утилитой Ping, вам необходимо добавить несколько глобальных переменных и модифицировать функцию DoWinsockProgram. В исходном тексте PING5.CPP содержится все остальное. Вот какие глобальные переменные необходимы: Функции PingDialog и PingDialogProc похожи на другие диалоговые процедуры из 24 ИП_Л_8 предыдущих версий Sockman. Первая создает диалоговое окно, а вторая — обрабатывает сообщения этого окна. Вот определение диалогового окна в файле SOCKMAN5.RC: Когда из меню Sockman выбирается опция Ping, новое диалоговое окно, определение которого (IDD_PING) вы только что видели, создается и выводится на экран. Диалоговое окно IDD_PING изображено на рис. 14.11. Далее, вы вводите имя или адрес сетевого компьютера, которому хотите послать ICMP-сообщение. Щелкнув мышью по кнопке Ping, вы начинаете сетевую Рис. 14.11. Диалоговое окно Ping программы Sockman операцию, выполняющую те же действия, что и в учебной программе QPing. Кнопка Cancel прекращает текущую операцию, а кнопка Exit закрывает диалоговое окно. Как показано ниже, в процедуре DoPingOperation из программы Sockman и в ее версии из программы QPing используются немного разные параметры. BOOL DoPingOperation(HWND hwnd, LPSTR lpszHostName, PDWORD pdwRoundTrip); В функции DoPingOperation программы Sockman указывается дескриптор окна, указатель на имя сетевого компьютера и указатель на буфер для хранения времени пробега датаграммы. Однако за исключением параметров, обе версии процедуры идентичны. Обе они вызывают одну и ту же функцию InternetChksum. Чтобы вызвать функцию PingDialog (она создает и выводит на экран диалоговое окно IDD_PING), в оператор case IDM_PING функции DoWinsockProgram необходимо внести следующие изменения: case IDM_PING: PingDialog(); break; Примечание: Функция DoWinsockProgram описывается в файле SOCKMAN5.CPP. Алгоритм работы утилиты Ping Операторы конструкции case WM_COMMAND функции PingDialogProc описывают алгоритм поведения утилиты в ответ на нажатия различных кнопок в диалоговом окне. Как показано ниже, эта конструкция содержит вложенную конструкцию case, обрабатывающую сообщения от трех диалоговых кнопок. В ответ на нажатие кнопки Ping ге25 ИП_Л_8 нерируется сообщение WM_COMMAND с параметром wParam, равным ШОК. Нажатие кнопки Cancel посылает сообщение WM_COMMAND с параметром wParam, равным IDCANCEL, а нажатие кнопки Exit — сообщение WM_COMMAND с параметром wParam, равным IDEXIT: 26 ИП_Л_8 Если блокирующая операция Ping запущена, а пользователь нажал кнопку Cancel (IDCANCEL), функция PingDialogProc вызывает WSACancelBlocking-Call, заставляющую Winsock прервать текущую блокирующую операцию. Нажатие кнопки Exit (IDEXIT) приводит к аналогичным действиям. Кроме прерывания текущей операции (если Ping уже запущен), PingDialogProc генерирует сообщение главному окну Sockman, очищающее и закрывающее диалоговое окно. Нажатие кнопки Ping (IDOK) вызывает все остальные, описанные в PingDialogProc операции. Сперва PingDialogProc обнуляет переменную dwTravelTime. В ней хранится время пробега ICMP-датаграммы «эхо», вычисленное функцией DoPingOperation. (Функция PingDialogProc передает указатель на dwTravelTime функции DoPingOperation.) Если операция Ping уже запущена (hPingTask равна true), Sockman предупреждает об этом пользователя. Пользователь может либо подождать, либо нажать кнопку Cancel, чтобы прервать операцию. Если операция Ping еще не запущена, функция PingDialogProc устанавливает значение переменной hPingTask равным символьной константе TASK_PING (она определена в файле SOCKMAN5.H) — таким образом, операция «регистрируется». Далее PingDialogProc заносит значение dwTravelTime (время пробега датаграммы) в текстовое окно IDC_PING_TIME, стирая тем самым предыдущее значение времени. Сразу после сброса текстового окна IDC_PING_TIME PingDialogProc извлекает имя сетевого компьютера из текстового окна IDC_PING_HOST. После этого PingDialogProc проверяет значение имени (при помощи функции lstrlen). Если длина имени не равна нулю, то есть имя существует, вызывается функция DoPingOperation, которая собственно и производит обмен 1СМР-да-таграммами. Как только DoPingOperation заканчивает работу, PingDialogProc докладывает о результатах и заносит новое значение dwTravelTime в текстовое окно IDC_PING_TIME. Кроме того, PingDialogProc выводит главное окно Sockman и гудком динамика извещает пользователя об окончании операции. Как к Sockman добавляются другие приложения? Версия программы Sockman, рассмотренная в этой главе, последняя. Теперь вы имеете представление о том, как в среде Windows программируются приложения Winsock API. Далее, вместо того чтобы добавлять новые утилиты в Sockman, мы сосредоточимся на разработке отдельных приложений Интернет. Ниже показано, как в Sockman можно добавить отдельное приложение или утилиту. Вы знаете, что все операции Winsock, перечисленные в меню Sockman, запускаются из процедуры DoWinsockProgram, проверяющей параметр wParam, чтобы определить, какая именно операция требуется. Как показано ниже, DoWinsockProgram выясняет, какое приложение — Mail или FTP — требуется, и запускает его при помощи функции Windows ShellExecute. В этом случае запускаются программы SockMail или SockFTP, в зависимости от выбора пользователя. Разумеется, этот выбор можно дополнить любым количеством других программ — достаточно немного 27 ИП_Л_8 скорректировать исходный текст. Предел развития программы Sockman находится только в вашем воображении. В нее можно добавлять все больше новых утилит или использовать в качестве стартовой площадки для запуска самостоятельных сетевых приложений. Подводя итоги В этой главе вы изучили протокол управляющих сообщений Интернет, ICMP. В основном, ICMP переносит разнообразные сообщения об ошибках при доставке данных или маршрутизации. Сообщения-запросы ICMP используются для отладки программного обеспечения сетевых компьютеров и разрешения проблем, связанных с межсетевой передачей данных. Вы узнали, как устроен и работает простой сокет, используемый, в частности, с протоколом ICMP. До того как перейти к главе 17, проверьте, хорошо ли вы уяснили следующие важные понятия: * Сообщения об ошибках ICMP относятся к ошибкам при доставке пакетов данных и маршрутизации. * Сообщения-запросы ICMP помогают определять источники сетевых неисправностей и отлаживать работу программ. * Для работы с простым сокетом прикладная программа должна самостоятельно выполнять функции транспортного уровня. * Для работы с простым сокетом прикладная программа обязана самостоятельно создавать и заполнять структуры данных требуемого протокола, в частности, заголовков IP и ICMP-датаграмм. 28