uIP 1.0
|
00001 /** 00002 * \addtogroup uip 00003 * @{ 00004 */ 00005 00006 /** 00007 * \file 00008 * Заголовочный файл для стека uIP TCP/IP. 00009 * \author Adam Dunkels <adam@dunkels.com> 00010 * 00011 * Этот заголовочный файл стека uIP TCP/IP содержит определения нескольких 00012 * макросов C, которые используются программами uIP, а также внутренними 00013 * структурами uIP, структурами заголовка TCP/IP и декларациями фунций. 00014 * 00015 */ 00016 00017 00018 /* 00019 * Copyright (c) 2001-2003, Adam Dunkels. 00020 * Все права зарезервированы. * 00021 * Повторное распространение, использование в исходном и двоичном виде, 00022 * с модификацией или без - разрешается, если выполняются следующие 00023 * условия: 00024 * 1. Распространение исходного кода должно сохранить вышеуказанную пометку 00025 * копирайта, этот список условий и следующую правовую оговорку. 00026 * 2. Распространение исходного кода должно сохранить вышеуказанную пометку 00027 * копирайта, этот список условий и следующую правовую оговорку в 00028 * документации и/или других материалах, которые будут предоставлены 00029 * вместе с распространяемыми материалами. 00030 * 3. Имя автора не может использоваться, чтобы подтвердить или продвинуть 00031 * продукты, написанные с использованием этого программного обеспечения 00032 * без специального на то разрешения. 00033 * 00034 * ЭТО ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ АВТОРОМ ``КАК ЕСТЬ'', БЕЗ 00035 * КАКОЙ-ЛИБО ЛЮБОЙ РАСШИРЕННОЙ ИЛИ ПОДРАЗУМЕВАЕМОЙ ГАРАНТИИ, ВКЛЮЧАЯ, 00036 * НО НЕ ОГРАНИЧИВАЯСЬ ЭТИМ, ГАРАНТИИ ВЫСОКОГО СПРОСА И ПРИГОДНОСТИ 00037 * ДЛЯ КОНКРЕТНОЙ ЦЕЛИ. АВТОР НИ ПРИ КАКИХ УСЛОВИЯХ НЕ ОТВЕТСТВЕНЕН 00038 * ЗА ЛЮБЫЕ УБЫТКИ - ПРЯМЫЕ, КОСВЕННЫЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ, ОБРАЗЦОВЫЕ 00039 * ИЛИ ПОСЛЕДОВАТЕЛЬНЫЕ (ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ЭТИМ, ТРЕБОВАНИЯ 00040 * ЗАМЕНЫ ТОВАРА ИЛИ СЕРВИСА; ПОТЕРИ ИСПОЛЬЗОВАНИЯ, ДАННЫХ ИЛИ ВЫГОДЫ; 00041 * ИЛИ ПРЕКРАЩЕНИЕ БИЗНЕСА), ОДНАКО ВЫЗВАННЫЕ ПО ЛЮБОЙ ТЕОРИИ ОТВЕТСТВЕННОСТИ, 00042 * ЛИБО В КОНТРАКТЕ, ПРЯМОЙ ОТВЕТСТВЕННОСТИ, ЛИБО В НАРУШЕНИИ ЗАКОННЫХ ПРАВ 00043 * (ВКЛЮЧАЯ ТАК ИЛИ ИНАЧЕ НЕБРЕЖНОСТЬ), ВОЗНИКАЮЩИЕ ВСЕГДА ИЗ ИСПОЛЬЗОВАНИЯ 00044 * ЭТОГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, ДАЖЕ ЕСЛИ БЫЛО ПРЕДУПРЕЖДЕНИЕ О ВОЗМОЖНОСТИ 00045 * ТАКОГО ПОВРЕЖДЕНИЯ. 00046 * 00047 * Этот файл является частью стека uIP TCP/IP. 00048 * 00049 * $Id: uip.h,v 1.40 2006/06/08 07:12:07 adam Exp $ 00050 * 00051 */ 00052 00053 #ifndef __UIP_H__ 00054 #define __UIP_H__ 00055 00056 #include "uipopt.h" 00057 00058 /** 00059 * Представление адреса IP. 00060 * 00061 */ 00062 typedef u16_t uip_ip4addr_t[2]; 00063 typedef u16_t uip_ip6addr_t[8]; 00064 #if UIP_CONF_IPV6 00065 typedef uip_ip6addr_t uip_ipaddr_t; 00066 #else /* UIP_CONF_IPV6 */ 00067 typedef uip_ip4addr_t uip_ipaddr_t; 00068 #endif /* UIP_CONF_IPV6 */ 00069 00070 /*---------------------------------------------------------------------------*/ 00071 /* Сначала приведены функции, которые должны вызываться из системы. 00072 * Инициализация, периодический таймер и приходящие пакеты обрабатываются 00073 * тремя следующими функциями. 00074 */ 00075 00076 /** 00077 * \defgroup uipconffunc Функции конфирурации uIP 00078 * @{ 00079 * 00080 * Функции конфигурации uIP используются для установки во время выполнения 00081 * (run-time) параметров, таких как например адресов IP. 00082 */ 00083 00084 /** 00085 * Устанавливает IP-адрес хоста. 00086 * 00087 * Адрес IP представлен как 4-байтный массив, где первый октет адреса IP 00088 * помещается первым в 4-байтном массиве. 00089 * 00090 * Пример: 00091 \code 00092 00093 uip_ipaddr_t addr; 00094 00095 uip_ipaddr(&addr, 192,168,1,2); 00096 uip_sethostaddr(&addr); 00097 00098 \endcode 00099 * \param addr Указатель на адрес IP типа uip_ipaddr_t; 00100 * 00101 * \sa uip_ipaddr() 00102 * 00103 * \hideinitializer 00104 */ 00105 #define uip_sethostaddr(addr) uip_ipaddr_copy(uip_hostaddr, (addr)) 00106 00107 /** 00108 * Получает IP-адрес хоста. 00109 * 00110 * Адрес IP представлен как 4-байтный массив, где первый октет адреса IP 00111 * помещается первым в 4-байтном массиве. 00112 * 00113 * Пример: 00114 \code 00115 uip_ipaddr_t hostaddr; 00116 00117 uip_gethostaddr(&hostaddr); 00118 \endcode 00119 * \param addr Указатель на переменную uip_ipaddr_t, которая будет заполнена 00120 * текущим сконфигурированным IP-адресом. 00121 * 00122 * \hideinitializer 00123 */ 00124 #define uip_gethostaddr(addr) uip_ipaddr_copy((addr), uip_hostaddr) 00125 00126 /** 00127 * Адрес IP шлюза (маршрутизатора) по умолчанию. 00128 * 00129 * \param addr Указатель на переменную uip_ipaddr_t, содержащую IP-адрес 00130 * для default router. 00131 * 00132 * \sa uip_ipaddr() 00133 * 00134 * \hideinitializer 00135 */ 00136 #define uip_setdraddr(addr) uip_ipaddr_copy(uip_draddr, (addr)) 00137 00138 /** 00139 * Устанавливает маску подсети (netmask). 00140 * 00141 * \param addr Указатель на переменную uip_ipaddr_t, содержащую 00142 * значение маски подсети. 00143 * 00144 * \sa uip_ipaddr() 00145 * 00146 * \hideinitializer 00147 */ 00148 #define uip_setnetmask(addr) uip_ipaddr_copy(uip_netmask, (addr)) 00149 00150 00151 /** 00152 * Получает IP-адрес шлюза по умолчанию. 00153 * 00154 * \param addr Указатель на переменную uip_ipaddr_t, которая будет 00155 * заполнена значением IP-адреса для default router. 00156 * 00157 * \hideinitializer 00158 */ 00159 #define uip_getdraddr(addr) uip_ipaddr_copy((addr), uip_draddr) 00160 00161 /** 00162 * Получает маску подсети (netmask). 00163 * 00164 * \param addr Указатель на переменную uip_ipaddr_t, которая будет 00165 * заполнена значением маски подсети. 00166 * 00167 * \hideinitializer 00168 */ 00169 #define uip_getnetmask(addr) uip_ipaddr_copy((addr), uip_netmask) 00170 00171 /** @} */ 00172 00173 /** 00174 * \defgroup uipinit Функции инициализации uIP 00175 * @{ 00176 * 00177 * Функции инициализации uIP используются для запуска uIP. 00178 */ 00179 00180 /** 00181 * Функция инициализации uIP. 00182 * 00183 * Эта функция должна быть вызвана в момент загрузки системы, чтобы 00184 * она проинициализировала стек uIP TCP/IP stack. 00185 */ 00186 void uip_init(void); 00187 00188 /** 00189 * Функция инициализации uIP. 00190 * 00191 * Эта функция должна быть вызвана в момент загрузки системы для 00192 * установки изначального ip_id. 00193 */ 00194 void uip_setipid(u16_t id); 00195 00196 /** @} */ 00197 00198 /** 00199 * \defgroup uipdevfunc Функции драйвера устройства uIP 00200 * @{ 00201 * 00202 * Эти функции используются сетевым драйвером устройства, который 00203 * работает совместно с uIP. 00204 */ 00205 00206 /** 00207 * Обрабатывает приходящий пакет. 00208 * 00209 * Эта функция должна быть вызвана, когда драйвер устройства принял 00210 * пакет через сеть. Пакет от драйвера устройства должен находиться 00211 * в буфере uip_buf, и длина пакета должна быть помещена в переменную 00212 * uip_len. 00213 * 00214 * Когда функция делает возврат, она может поместить исходящий пакет 00215 * в тот же буфер uip_buf. Если это так, то переменная uip_len 00216 * устанавливается в значение длины этого пакета. Если нет пакета для 00217 * отправки, то значение переменной uip_len устанавливается равным 0. 00218 * 00219 * В коде ниже показан обычный способ вызова функции. 00220 \code 00221 uip_len = devicedriver_poll(); 00222 if(uip_len > 0) { 00223 uip_input(); 00224 if(uip_len > 0) { 00225 devicedriver_send(); 00226 } 00227 } 00228 \endcode 00229 * 00230 * \note Если Вы пишете драйвер устройства uIP, которому нужен ARP 00231 * (Address Resolution Protocol), например когда uIP работает через 00232 * Ethernet, то Вам нужно перед вызовом этой функции вызвать 00233 * код uIP ARP: 00234 \code 00235 #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) 00236 uip_len = ethernet_devicedrver_poll(); 00237 if(uip_len > 0) { 00238 if(BUF->type == HTONS(UIP_ETHTYPE_IP)) { 00239 uip_arp_ipin(); 00240 uip_input(); 00241 if(uip_len > 0) { 00242 uip_arp_out(); 00243 ethernet_devicedriver_send(); 00244 } 00245 } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) { 00246 uip_arp_arpin(); 00247 if(uip_len > 0) { 00248 ethernet_devicedriver_send(); 00249 } 00250 } 00251 \endcode 00252 * 00253 * \hideinitializer 00254 */ 00255 #define uip_input() uip_process(UIP_DATA) 00256 00257 /** 00258 * Периодическая обработка соединения, идентифицируемого по его номеру. 00259 * 00260 * Эта функция делает необходимые периодические обработки (таймеры, 00261 * поллинг) для соединения uIP TCP, и должна вызываться по срабатыванию 00262 * периодического таймера uIP. Она должна быть вызвана для каждого 00263 * соединения, назависимо от того - открыто это соединение или закрыто. 00264 * 00265 * Когда функция делает возврат, она может поместить в буфер пакета uIP 00266 * исходящий пакет, ожидающий отправки. Если это так, то переменная 00267 * uip_len будет установлена в ненулевое значение. Чтобы отправить пакет, 00268 * должен быть вызван драйвер устройства. 00269 * 00270 * Обычно функция вызывается из цикла for() примерно так: 00271 \code 00272 for(i = 0; i < UIP_CONNS; ++i) { 00273 uip_periodic(i); 00274 if(uip_len > 0) { 00275 devicedriver_send(); 00276 } 00277 } 00278 \endcode 00279 * 00280 * \note Если Вы пишете драйвер устройства uIP, которому нужен ARP 00281 * (Address Resolution Protocol), например когда uIP работает через 00282 * Ethernet, то Вам нужно вызвать функцию uip_arp_out() перед вызовом 00283 * драйвера устройства: 00284 \code 00285 for(i = 0; i < UIP_CONNS; ++i) { 00286 uip_periodic(i); 00287 if(uip_len > 0) { 00288 uip_arp_out(); 00289 ethernet_devicedriver_send(); 00290 } 00291 } 00292 \endcode 00293 * 00294 * \param conn Номер соединения, которое периодически опрашивается. 00295 * 00296 * \hideinitializer 00297 */ 00298 #define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \ 00299 uip_process(UIP_TIMER); } while (0) 00300 00301 /** 00302 * 00303 * 00304 */ 00305 #define uip_conn_active(conn) (uip_conns[conn].tcpstateflags != UIP_CLOSED) 00306 00307 /** 00308 * Выполняет периодические обработки соединения, идентифицируемого по 00309 * указателю на его структуру. 00310 * 00311 * То же самое, что и uip_periodic(), однако принимает в аргументе указатель 00312 * на реальную структуру uip_conn вместо целого числа. Эта функция может быть 00313 * использована для принудиельной периодической обработки отдельного соединения. 00314 * 00315 * \param conn Указатель на структуру uip_conn для обрабатываемого соединения. 00316 * 00317 * \hideinitializer 00318 */ 00319 #define uip_periodic_conn(conn) do { uip_conn = conn; \ 00320 uip_process(UIP_TIMER); } while (0) 00321 00322 /** 00323 * Запрашивает отдельное соединение, которое должно быть опрошено. 00324 * 00325 * То же самое, что и uip_periodic_conn(), но не делает обработку по таймеру. 00326 * Приложение опрашивает появление новых данных. 00327 * 00328 * \param conn Указатель на структуру uip_conn для обрабатываемого 00329 * соединения. 00330 * 00331 * \hideinitializer 00332 */ 00333 #define uip_poll_conn(conn) do { uip_conn = conn; \ 00334 uip_process(UIP_POLL_REQUEST); } while (0) 00335 00336 00337 #if UIP_UDP 00338 /** 00339 * Периодическая обработка соединения UDP, идентифицированного по его номеру. 00340 * 00341 * Эта функция точно такая же, как и uip_periodic(), но для соединений 00342 * UDP. Она вызывается точно так же, как и функция uip_periodic(): 00343 \code 00344 for(i = 0; i < UIP_UDP_CONNS; i++) { 00345 uip_udp_periodic(i); 00346 if(uip_len > 0) { 00347 devicedriver_send(); 00348 } 00349 } 00350 \endcode 00351 * 00352 * \note Как и при использовании функции uip_periodic(), нужно позаботиться 00353 * taken о том, как использовать её при задействовании uIP вместе с ARP и Ethernet: 00354 \code 00355 for(i = 0; i < UIP_UDP_CONNS; i++) { 00356 uip_udp_periodic(i); 00357 if(uip_len > 0) { 00358 uip_arp_out(); 00359 ethernet_devicedriver_send(); 00360 } 00361 } 00362 \endcode 00363 * 00364 * \param conn Номер обрабатываемого соединения UDP. 00365 * 00366 * \hideinitializer 00367 */ 00368 #define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \ 00369 uip_process(UIP_UDP_TIMER); } while (0) 00370 00371 /** 00372 * Периодическая обработка соединения UDP, идентифицированного по указателю 00373 * на его структуру. 00374 * 00375 * То же самое, что и uip_udp_periodic(), но в качестве аргумента вместо 00376 * целого числа принимает указатель на реальную структуру uip_conn. 00377 * Эта функция может использоваться для принудительной периодической обработки 00378 * отдельного соединения. 00379 * 00380 * \param conn Указатель на структуру uip_udp_conn для обрабатываемого 00381 * соединения. 00382 * 00383 * \hideinitializer 00384 */ 00385 #define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \ 00386 uip_process(UIP_UDP_TIMER); } while (0) 00387 00388 00389 #endif /* UIP_UDP */ 00390 00391 /** 00392 * Буфер пакета uIP. 00393 * 00394 * Массив uip_buf используется для того, чтобы хранить входящие и исходящие 00395 * пакеты. Драйвер устройства должен поместить в этот буфер приходящие данные. 00396 * Когда данные отправляются, драйвер устройства должен читать заголовки уровня 00397 * линка и заголовки TCP/IP из этого буфера. Размер заголовков уровня линка 00398 * конфигурируется дефайном UIP_LLH_LEN. 00399 * 00400 * \note Данные приложения должны быть помещены в этот буфер, так что драйвер 00401 * устройства должен читать их с места, указанного через указатель uip_appdata, 00402 * как это показано в следующем примере: 00403 \code 00404 void 00405 devicedriver_send(void) 00406 { 00407 hwsend(&uip_buf[0], UIP_LLH_LEN); 00408 if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) { 00409 hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN); 00410 } else { 00411 hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN); 00412 hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN); 00413 } 00414 } 00415 \endcode 00416 */ 00417 extern u8_t uip_buf[UIP_BUFSIZE+2]; 00418 00419 /** @} */ 00420 00421 /*---------------------------------------------------------------------------*/ 00422 /* Функции, которые используются программой приложения uIP. Открытие и 00423 * и закрытие соединений, отправка и прием данных и т. п. действия 00424 * обрбатываются следующими функциями. 00425 */ 00426 /** 00427 * \defgroup uipappfunc Функции приложения uIP 00428 * @{ 00429 * 00430 * Функции, используемые в приложении, работающем поверх uIP. 00431 */ 00432 00433 /** 00434 * Запуск прослушивания указанного порта. 00435 * 00436 * \note Поскольку эта функция ожидает номер порта с сетевым порядком байт, 00437 * то при необходимости должно быть применено преобразование HTONS() или htons(). 00438 * 00439 \code 00440 uip_listen(HTONS(80)); 00441 \endcode 00442 * 00443 * \param port 16-битный номер порта с сетевым порядком байт. 00444 */ 00445 void uip_listen(u16_t port); 00446 00447 /** 00448 * Остановить прослушивание указанного порта. 00449 * 00450 * \note Поскольку эта функция ожидает номер порта с сетевым порядком байт, 00451 * то при необходимости должно быть применено преобразование HTONS() или htons(). 00452 * 00453 \code 00454 uip_unlisten(HTONS(80)); 00455 \endcode 00456 * 00457 * \param port 16-битный номер порта с сетевым порядком байт. 00458 */ 00459 void uip_unlisten(u16_t port); 00460 00461 /** 00462 * Соединение с дальним хостом (remote host), используя TCP. 00463 * 00464 * Эта функция используется для запуска нового соединения с указанным портом 00465 * указанного хоста. Она выделяет новый идентификатор соединения, 00466 * устанавливает соединение в состояние SYN_SENT и устанавливает таймер 00467 * ретрансмиссии в 0. Это приведет к тому, что будет передан сегмент TCP SYN 00468 * в следующий раз, когда это соединение будет периодически обработано, 00469 * что будет сделано обычно через 0.5 секунд после вызова uip_connect(). 00470 * 00471 * \note Эта функция доступна, только если активна поддержка активного открытого 00472 * соединения путем задания UIP_ACTIVE_OPEN на значение 1 в файле uipopt.h. 00473 * 00474 * \note Поскольку эта функция ожидает номер порта с сетевым порядком байт, 00475 * то при необходимости должно быть применено преобразование HTONS() или htons(). 00476 * 00477 \code 00478 uip_ipaddr_t ipaddr; 00479 00480 uip_ipaddr(&ipaddr, 192,168,1,2); 00481 uip_connect(&ipaddr, HTONS(80)); 00482 \endcode 00483 * 00484 * \param ripaddr IP-адрес для remote hot. 00485 * 00486 * \param port 16-битный номер порта с сетевым порядком байт. 00487 * 00488 * \return Указатель на идентификатор соединения uI для нового соединения, 00489 * или NULL, если не может быть выделено новое соединение. 00490 * 00491 */ 00492 struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, u16_t port); 00493 00494 00495 00496 /** 00497 * \internal 00498 * 00499 * Проверка - есть ли на соединении потерянные (например не подтвержденные) 00500 * данные. 00501 * 00502 * \param conn Указатель на структуру uip_conn для соединения. 00503 * 00504 * \hideinitializer 00505 */ 00506 #define uip_outstanding(conn) ((conn)->len) 00507 00508 /** 00509 * Посылает данные через текущее соединение. 00510 * 00511 * Эта функция используется для отправки одного сегмента данных TCP. 00512 * Могут отправлять данные только приложения, которые были вызваны из 00513 * uIP для обработки события. 00514 * 00515 * Количество данных, которое было на самом деле отправлено после вызова 00516 * этой функции, определяется максимальным количеством данны, которое 00517 * позволяет TCP. uIP автоматически будет урезать данные, так чтобы 00518 * было отправлено допустимое количество. Может быть использована 00519 * фукнция uip_mss(), чтобы запросить у uIP количество данных, которое 00520 * будет отправлено в действительности. 00521 * 00522 * \note Эта функция не дает гарантии, что посылаемые данные дойдут до 00523 * получателя. Если данные будут потеряны в сети, приложение будет вызвано 00524 * с установленным событием uip_rexmit(). Затем приложение заново отправит 00525 * данные, используя эту фукнцию. 00526 * 00527 * \param data Указатель на данные для отправки. 00528 * 00529 * \param len Максимальное количество данных для отправки. 00530 * 00531 * \hideinitializer 00532 */ 00533 void uip_send(const void *data, int len); 00534 00535 /** 00536 * Длина любых пришедшик данны, которые в настоящий момент доступны 00537 * (если доступны) в буфере uip_appdata. 00538 * 00539 * Перед этим может быть использована функция uip_data(), чтобы проверить, 00540 * есть ли вообще доступные данные. 00541 * 00542 * \hideinitializer 00543 */ 00544 /*void uip_datalen(void);*/ 00545 #define uip_datalen() uip_len 00546 00547 /** 00548 * Длина любых данные вне диапазона (out-of-band data, или urgent data, 00549 * т. е. данные, требующие срочной доставки), которые поступили 00550 * на соединении. 00551 * 00552 * \note Чтобы эта функция была разрешена, должен быть установлен 00553 * конфигурационный параметр UIP_URGDATA. 00554 * 00555 * \hideinitializer 00556 */ 00557 #define uip_urgdatalen() uip_urglen 00558 00559 /** 00560 * Закрывает текущее соединение. 00561 * 00562 * Эта функция должным образом закроет текущее соединение. 00563 * 00564 * \hideinitializer 00565 */ 00566 #define uip_close() (uip_flags = UIP_CLOSE) 00567 00568 /** 00569 * Обрыв (Abort) текущего соединения. 00570 * 00571 * Эта функция оборвет (сбросит) текущее соедиение, что обычно используется, 00572 * когда случилась ошибка, что не дает право использовать функцию uip_close(). 00573 * 00574 * \hideinitializer 00575 */ 00576 #define uip_abort() (uip_flags = UIP_ABORT) 00577 00578 /** 00579 * Говорит посылающему данные хосту, что нужно остановить отправку данных. 00580 * 00581 * Эта функция закроет окно приема, чем приведет к остановке приема данных 00582 * для текущего соединения. 00583 * 00584 * \hideinitializer 00585 */ 00586 #define uip_stop() (uip_conn->tcpstateflags |= UIP_STOPPED) 00587 00588 /** 00589 * Проверяет, было ли текущее соединение ранее остановлено вызовом uip_stop(). 00590 * 00591 * \hideinitializer 00592 */ 00593 #define uip_stopped(conn) ((conn)->tcpstateflags & UIP_STOPPED) 00594 00595 /** 00596 * Перезапускает текущее соединение, если оно было ранее остановлено 00597 * вызовом uip_stop(). 00598 * 00599 * Эта функция снова откроет окно приема, что приведет к возобновлению 00600 * приема данных на текущем соединении. 00601 * 00602 * \hideinitializer 00603 */ 00604 #define uip_restart() do { uip_flags |= UIP_NEWDATA; \ 00605 uip_conn->tcpstateflags &= ~UIP_STOPPED; \ 00606 } while(0) 00607 00608 00609 /* Проверки uIP, которые она может делать для того, чтобы определить, 00610 в каком состоянии находится соединение, и что должна делать функция 00611 приложения. */ 00612 00613 /** 00614 * Текущее соединение является соединением UDP? 00615 * 00616 * Эта функция проверяет, является ли текущее соединение соединением UDP. 00617 * 00618 * \hideinitializer 00619 * 00620 */ 00621 #define uip_udpconnection() (uip_conn == NULL) 00622 00623 /** 00624 * Есть ли новые данные? 00625 * 00626 * Вернет не 0, если для приложения имеются новые данные, которые 00627 * представлены по указателю. Размер доступных данных можно узнать 00628 * по значению переменной uip_len. 00629 * 00630 * \hideinitializer 00631 */ 00632 #define uip_newdata() (uip_flags & UIP_NEWDATA) 00633 00634 /** 00635 * Были ли подтверждены ранее отправленные данные? 00636 * 00637 * Вернет не 0, если ранее посланные данные были подтверждены стороной 00638 * remote host. Это означает, что приложение может послать новые данные. 00639 * 00640 * \hideinitializer 00641 */ 00642 #define uip_acked() (uip_flags & UIP_ACKDATA) 00643 00644 /** 00645 * Соединение все еще установлено? 00646 * 00647 * Вернет не 0, если текущее соедиение еще работает, и подключено к 00648 * remote host. Это случится в обоих случаях, если соединение активно 00649 * открыто (вызовом uip_connect()) или пассивно открыто (вызовом 00650 * uip_listen()). 00651 * 00652 * \hideinitializer 00653 */ 00654 #define uip_connected() (uip_flags & UIP_CONNECTED) 00655 00656 /** 00657 * Было ли соединение закрыто на дальнем конце? 00658 * 00659 * Не 0, если соединение было закрыто по инициативе remote host. 00660 * Если это так, то приложение может сделать необходимые очистки. 00661 * 00662 * \hideinitializer 00663 */ 00664 #define uip_closed() (uip_flags & UIP_CLOSE) 00665 00666 /** 00667 * Было ли соединение оборвано (aborted) на другом конце? 00668 * 00669 * Не 0, если текущее было оборвано (сброшено) по инициативе 00670 * remote host. 00671 * 00672 * \hideinitializer 00673 */ 00674 #define uip_aborted() (uip_flags & UIP_ABORT) 00675 00676 /** 00677 * Истек ли таймаут на соединении? 00678 * 00679 * Не 0, если текущее соединение было оборвано из за слишком большого 00680 * количества ретрансмиссий. 00681 * 00682 * \hideinitializer 00683 */ 00684 #define uip_timedout() (uip_flags & UIP_TIMEDOUT) 00685 00686 /** 00687 * Нужно ли отправить заново ранее посланные данные? 00688 * 00689 * Вернет не 0, если ранее отправленные данные были потеряны в сети, 00690 * в этом случае приложение должно заново их отправить (retransmit). 00691 * Приложение должно отправить точно те же данные, которые оно отправило 00692 * последний раз, используя функцию uip_send(). 00693 * 00694 * \hideinitializer 00695 */ 00696 #define uip_rexmit() (uip_flags & UIP_REXMIT) 00697 00698 /** 00699 * Соединение опрашивается от uIP? 00700 * 00701 * Не 0, если причина вызова приложения в том, что соединение было неактивно 00702 * некоторое время, и должно быть опрошено. 00703 * 00704 * Событие опроса (polling event) может быть использовано для отправки 00705 * данных без ожидания, что remote host отправит данные. 00706 * 00707 * \hideinitializer 00708 */ 00709 #define uip_poll() (uip_flags & UIP_POLL) 00710 00711 /** 00712 * Получает максимальный начальный размер сегмента (MSS) текущего 00713 * соединения. 00714 * 00715 * \hideinitializer 00716 */ 00717 #define uip_initialmss() (uip_conn->initialmss) 00718 00719 /** 00720 * Получает текущий максимальный размер сегмента, который может быть 00721 * отправлен через текущее соединение. 00722 * 00723 * Такущий максимальный размер сегмента, который можно отправить 00724 * на соединении, вычисляется на основе окна прием и MSS соединения 00725 * (которое также доступно через вызов uip_initialmss()). 00726 * 00727 * \hideinitializer 00728 */ 00729 #define uip_mss() (uip_conn->mss) 00730 00731 /** 00732 * Устанавливает новое соединение UDP. 00733 * 00734 * Эта функция устанавливает новое соединение UDP. Функция автоматически 00735 * выделит неиспользуемый локальный порт для нового соединения. Однако может 00736 * быть выбран другой порт с помощью вызова uip_udp_bind() после того, 00737 * как была вызвана функция uip_udp_new(). 00738 * 00739 * Пример: 00740 \code 00741 uip_ipaddr_t addr; 00742 struct uip_udp_conn *c; 00743 00744 uip_ipaddr(&addr, 192,168,2,1); 00745 c = uip_udp_new(&addr, HTONS(12345)); 00746 if(c != NULL) { 00747 uip_udp_bind(c, HTONS(12344)); 00748 } 00749 \endcode 00750 * \param ripaddr IP-адрес для remote host. 00751 * 00752 * \param rport Номер порта remote host с сетевым порядком байт. 00753 * 00754 * \return Структура uip_udp_conn для нового соединения или NULL, 00755 * если не может быть выделено соединение. 00756 */ 00757 struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport); 00758 00759 /** 00760 * Удаляет соединение UDP. 00761 * 00762 * \param conn Указатель на структуру uip_udp_conn для соединения. 00763 * 00764 * \hideinitializer 00765 */ 00766 #define uip_udp_remove(conn) (conn)->lport = 0 00767 00768 /** 00769 * Привязка соединения UDP к локальному порту. 00770 * 00771 * \param conn Указатель на структуру uip_udp_conn для соединения. 00772 * 00773 * \param port Номер локального порта с сетевым порядком байт. 00774 * 00775 * \hideinitializer 00776 */ 00777 #define uip_udp_bind(conn, port) (conn)->lport = port 00778 00779 /** 00780 * Отправляет датаграмму UDP длиной len через текущее соединение. 00781 * 00782 * Эта функция может быть вызвана только в ответ на событие UDP (опроса 00783 * или поступления новых данных). Данные должны быть представлены в буфере 00784 * uip_buf, в том месте, на которое указывает указатель uip_appdata. 00785 * 00786 * \param len Длина данных в буфере uip_buf. 00787 * 00788 * \hideinitializer 00789 */ 00790 #define uip_udp_send(len) uip_send((char *)uip_appdata, len) 00791 00792 /** @} */ 00793 00794 /* Вспомогательные и конвертирующие функции uIP. */ 00795 00796 /** 00797 * \defgroup uipconvfunc Функции преобразований uIP 00798 * @{ 00799 * 00800 * Эти функции могут использоваться для преобразования между разными 00801 * форматами данных, используемых в uIP. 00802 */ 00803 00804 /** 00805 * Конструирует адрес IP из 4 байт. 00806 * 00807 * Эта функция составляет IP-адрес того типа, который обрабатывает 00808 * внутри себя uIP. Эта функция удобна, чтобы указать IP-адреса 00809 * для использования, например, с функцией uip_connect(). 00810 * 00811 * Пример: 00812 \code 00813 uip_ipaddr_t ipaddr; 00814 struct uip_conn *c; 00815 00816 uip_ipaddr(&ipaddr, 192,168,1,2); 00817 c = uip_connect(&ipaddr, HTONS(80)); 00818 \endcode 00819 * 00820 * \param addr Указатель на переменную uip_ipaddr_t, которая будет 00821 * заполнена адресом IP. 00822 * 00823 * \param addr0 Первый октет адреса IP. 00824 * \param addr1 Второй октет адреса IP. 00825 * \param addr2 Третий октет адреса IP. 00826 * \param addr3 Четвертый октет адреса IP. 00827 * 00828 * \hideinitializer 00829 */ 00830 #define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \ 00831 ((u16_t *)(addr))[0] = HTONS(((addr0) << 8) | (addr1)); \ 00832 ((u16_t *)(addr))[1] = HTONS(((addr2) << 8) | (addr3)); \ 00833 } while(0) 00834 00835 /** 00836 * Составляет адрес IPv6 из восьми 16-битных слов. 00837 * 00838 * Эта функция конструирует адрес IPv6. 00839 * 00840 * \hideinitializer 00841 */ 00842 #define uip_ip6addr(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7) do { \ 00843 ((u16_t *)(addr))[0] = HTONS((addr0)); \ 00844 ((u16_t *)(addr))[1] = HTONS((addr1)); \ 00845 ((u16_t *)(addr))[2] = HTONS((addr2)); \ 00846 ((u16_t *)(addr))[3] = HTONS((addr3)); \ 00847 ((u16_t *)(addr))[4] = HTONS((addr4)); \ 00848 ((u16_t *)(addr))[5] = HTONS((addr5)); \ 00849 ((u16_t *)(addr))[6] = HTONS((addr6)); \ 00850 ((u16_t *)(addr))[7] = HTONS((addr7)); \ 00851 } while(0) 00852 00853 /** 00854 * Копирует IP-адрес в другой IP-адрес. 00855 * 00856 * Копирует IP-адрес с одного места в другое. 00857 * 00858 * Пример: 00859 \code 00860 uip_ipaddr_t ipaddr1, ipaddr2; 00861 00862 uip_ipaddr(&ipaddr1, 192,16,1,2); 00863 uip_ipaddr_copy(&ipaddr2, &ipaddr1); 00864 \endcode 00865 * 00866 * \param dest Место назначения копии. 00867 * \param src Исходные данные, откуда IP будет копироваться. 00868 * 00869 * \hideinitializer 00870 */ 00871 #if !UIP_CONF_IPV6 00872 #define uip_ipaddr_copy(dest, src) do { \ 00873 ((u16_t *)dest)[0] = ((u16_t *)src)[0]; \ 00874 ((u16_t *)dest)[1] = ((u16_t *)src)[1]; \ 00875 } while(0) 00876 #else /* !UIP_CONF_IPV6 */ 00877 #define uip_ipaddr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip6addr_t)) 00878 #endif /* !UIP_CONF_IPV6 */ 00879 00880 /** 00881 * Сравнение двух IP-адресов 00882 * 00883 * Сравнивает два IP-адреса. 00884 * 00885 * Пример: 00886 \code 00887 uip_ipaddr_t ipaddr1, ipaddr2; 00888 00889 uip_ipaddr(&ipaddr1, 192,16,1,2); 00890 if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) { 00891 printf("They are the same"); 00892 } 00893 \endcode 00894 * 00895 * \param addr1 Первый IP-адрес. 00896 * \param addr2 Второй IP-адрес. 00897 * 00898 * \hideinitializer 00899 */ 00900 #if !UIP_CONF_IPV6 00901 #define uip_ipaddr_cmp(addr1, addr2) (((u16_t *)addr1)[0] == ((u16_t *)addr2)[0] && \ 00902 ((u16_t *)addr1)[1] == ((u16_t *)addr2)[1]) 00903 #else /* !UIP_CONF_IPV6 */ 00904 #define uip_ipaddr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0) 00905 #endif /* !UIP_CONF_IPV6 */ 00906 00907 /** 00908 * Сравнение двух адресов IP с сетевой маской 00909 * 00910 * Сравнивает два адреса IP с сетевой маской. Маски используются, чтобы маскировать 00911 * биты, которые должны сравниваться. 00912 * 00913 * Пример: 00914 \code 00915 uip_ipaddr_t ipaddr1, ipaddr2, mask; 00916 00917 uip_ipaddr(&mask, 255,255,255,0); 00918 uip_ipaddr(&ipaddr1, 192,16,1,2); 00919 uip_ipaddr(&ipaddr2, 192,16,1,3); 00920 if(uip_ipaddr_maskcmp(&ipaddr1, &ipaddr2, &mask)) { 00921 printf("They are the same"); 00922 } 00923 \endcode 00924 * 00925 * \param addr1 Первый IP-адрес. 00926 * \param addr2 Второй IP-адрес. 00927 * \param mask Сетевая маска. 00928 * 00929 * \hideinitializer 00930 */ 00931 #define uip_ipaddr_maskcmp(addr1, addr2, mask) \ 00932 (((((u16_t *)addr1)[0] & ((u16_t *)mask)[0]) == \ 00933 (((u16_t *)addr2)[0] & ((u16_t *)mask)[0])) && \ 00934 ((((u16_t *)addr1)[1] & ((u16_t *)mask)[1]) == \ 00935 (((u16_t *)addr2)[1] & ((u16_t *)mask)[1]))) 00936 00937 00938 /** 00939 * Маскирует сетевую часть адреса IP. 00940 * 00941 * Выделяет маской сетевую часть от IP-адреса, которая получается от адреса 00942 * и сетевой маски. 00943 * 00944 * Пример: 00945 \code 00946 uip_ipaddr_t ipaddr1, ipaddr2, netmask; 00947 00948 uip_ipaddr(&ipaddr1, 192,16,1,2); 00949 uip_ipaddr(&netmask, 255,255,255,0); 00950 uip_ipaddr_mask(&ipaddr2, &ipaddr1, &netmask); 00951 \endcode 00952 * 00953 * В предыдущем примере переменная "ipaddr2" будет содержать IP-адрес 00954 * 192.168.1.0. 00955 * 00956 * \param dest Место, куда будет помещен результат. 00957 * \param src Адрес IP. 00958 * \param mask Сетевая маска. 00959 * 00960 * \hideinitializer 00961 */ 00962 #define uip_ipaddr_mask(dest, src, mask) do { \ 00963 ((u16_t *)dest)[0] = ((u16_t *)src)[0] & ((u16_t *)mask)[0]; \ 00964 ((u16_t *)dest)[1] = ((u16_t *)src)[1] & ((u16_t *)mask)[1]; \ 00965 } while(0) 00966 00967 /** 00968 * Получение первого октета от адреса IP. 00969 * 00970 * Выбирает первый октет из IP-адреса. 00971 * 00972 * Пример: 00973 \code 00974 uip_ipaddr_t ipaddr; 00975 u8_t octet; 00976 00977 uip_ipaddr(&ipaddr, 1,2,3,4); 00978 octet = uip_ipaddr1(&ipaddr); 00979 \endcode 00980 * 00981 * В предыдущем примере переменная "octet" будет содержать значение 1. 00982 * 00983 * \hideinitializer 00984 */ 00985 #define uip_ipaddr1(addr) (htons(((u16_t *)(addr))[0]) >> 8) 00986 00987 /** 00988 * Получение второго октета от адреса IP. 00989 * 00990 * Выбирает второй октет из IP-адреса. 00991 * 00992 * Пример: 00993 \code 00994 uip_ipaddr_t ipaddr; 00995 u8_t octet; 00996 00997 uip_ipaddr(&ipaddr, 1,2,3,4); 00998 octet = uip_ipaddr2(&ipaddr); 00999 \endcode 01000 * 01001 * В предыдущем примере переменная "octet" будет содержать значение 2. 01002 * 01003 * \hideinitializer 01004 */ 01005 #define uip_ipaddr2(addr) (htons(((u16_t *)(addr))[0]) & 0xff) 01006 01007 /** 01008 * Получение третьего октета от адреса IP. 01009 * 01010 * Выбирает третий октет из IP-адреса. 01011 * 01012 * Пример: 01013 \code 01014 uip_ipaddr_t ipaddr; 01015 u8_t octet; 01016 01017 uip_ipaddr(&ipaddr, 1,2,3,4); 01018 octet = uip_ipaddr3(&ipaddr); 01019 \endcode 01020 * 01021 * В предыдущем примере переменная "octet" будет содержать значение 3. 01022 * 01023 * \hideinitializer 01024 */ 01025 #define uip_ipaddr3(addr) (htons(((u16_t *)(addr))[1]) >> 8) 01026 01027 /** 01028 * Получение четвертого октета от адреса IP. 01029 * 01030 * Выбирает четвертый октет из IP-адреса. 01031 * 01032 * Пример: 01033 \code 01034 uip_ipaddr_t ipaddr; 01035 u8_t octet; 01036 01037 uip_ipaddr(&ipaddr, 1,2,3,4); 01038 octet = uip_ipaddr4(&ipaddr); 01039 \endcode 01040 * 01041 * В предыдущем примере переменная "octet" будет содержать значение 4. 01042 * 01043 * \hideinitializer 01044 */ 01045 #define uip_ipaddr4(addr) (htons(((u16_t *)(addr))[1]) & 0xff) 01046 01047 /** 01048 * Преобразует 16-битное число с порядком байт хоста в число с 01049 * сетевым порядком байт. 01050 * 01051 * Этот макрос главным образом используется для преобразования констант 01052 * номера порта. Для преобразования переменных в сетевой порядок байт 01053 * используйте вместо этого функцию htons(). 01054 * 01055 * \hideinitializer 01056 */ 01057 #ifndef HTONS 01058 # if UIP_BYTE_ORDER == UIP_BIG_ENDIAN 01059 # define HTONS(n) (n) 01060 # else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ 01061 # define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8)) 01062 # endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ 01063 #else 01064 #error "HTONS already defined!" 01065 #endif /* HTONS */ 01066 01067 /** 01068 * Преобразует 16-битное число с порядком байт хоста в число с 01069 * сетевым порядком байт. 01070 * 01071 * Этот функция главным образом используется для преобразования переменных 01072 * номера порта. Для преобразования констант в сетевой порядок байт 01073 * используйте вместо этого макрос HTONS(). 01074 */ 01075 #ifndef htons 01076 u16_t htons(u16_t val); 01077 #endif /* htons */ 01078 #ifndef ntohs 01079 #define ntohs htons 01080 #endif 01081 01082 /** @} */ 01083 01084 /** 01085 * Указатель на данные приложения, находящиеся в буфере пакета. 01086 * 01087 * Этот указатель указывает на данные приложения, когда вызывается функция 01088 * приложения. Если приложению нужно отправить данные, то оно может 01089 * использовать это пространство для записи туда данных перед вызовом 01090 * uip_send(). 01091 */ 01092 extern void *uip_appdata; 01093 01094 #if UIP_URGDATA > 0 01095 /* u8_t *uip_urgdata: 01096 * 01097 * Этот указатель указывает на любые urgent data, которые были приняты. 01098 * Он представлен, если была разрешена компиляция поддержки urgent data 01099 * (UIP_URGDATA). 01100 */ 01101 extern void *uip_urgdata; 01102 #endif /* UIP_URGDATA > 0 */ 01103 01104 01105 /** 01106 * \defgroup uipdrivervars Переменные, используемые драйверами устройства uIP 01107 * @{ 01108 * 01109 * uIP имеет несколько глобальных переменных, которе используются в драйверах 01110 * устройства для uIP. 01111 */ 01112 01113 /** 01114 * Длина пакета в буфере uip_buf. 01115 * 01116 * Глобальная переменная uip_len содержит длину пакета в буфере 01117 * uip_buf. 01118 * 01119 * Когда сетевой драйвер устройства вызывает функцию ввода uIP, переменная 01120 * uip_len должна быть установлена на значение длины пакета в буфере 01121 * uip_buf. 01122 * 01123 * Когда отправляются пакеты, драйвер устройства должен использовать содержимое 01124 * переменной uip_len, чтобы определить длину уходящего пакета. 01125 * 01126 */ 01127 extern u16_t uip_len; 01128 01129 /** @} */ 01130 01131 #if UIP_URGDATA > 0 01132 extern u16_t uip_urglen, uip_surglen; 01133 #endif /* UIP_URGDATA > 0 */ 01134 01135 01136 /** 01137 * Представление соединения TCP в стеке uIP. 01138 * 01139 * Структура uip_conn используется для идентификации соединения. Все поля 01140 * структуры, кроме одного, считаются для приложения полями только для 01141 * чтения. Исключение составляет поле appstate, назначение которого - 01142 * разрешить приложению сохранить свое состояние (например, файловые 01143 * указатели) для соединения. Тип этого поля конфигурируется в файле 01144 * заголовка "uipopt.h". 01145 */ 01146 struct uip_conn { 01147 uip_ipaddr_t ripaddr; /**< Адрес IP для remote host. */ 01148 01149 u16_t lport; /**< Локальный порт TCP, с сетевым порядком байт. */ 01150 u16_t rport; /**< Локальная копия порта TCP дальней стороны 01151 соединения, с сетевым порядком байт. */ 01152 01153 u8_t rcv_nxt[4]; /**< Номер последоательности, который ожидается 01154 следующим для приема. */ 01155 u8_t snd_nxt[4]; /**< Номер последовательности, который был нами 01156 отправлен последним. */ 01157 u16_t len; /**< Длина ранее отправленных данных. */ 01158 u16_t mss; /**< Текущий максимальный размер сегмента для 01159 соединения. */ 01160 u16_t initialmss; /**< Начальный максимальный размер сегмента для 01161 соединения. */ 01162 u8_t sa; /**< Переменная состояния вычисления таймаута 01163 ретрансмиссии. */ 01164 u8_t sv; /**< Переменная состояния вычисления таймаута 01165 ретрансмиссии. */ 01166 u8_t rto; /**< Таймаут ретрансмиссии. */ 01167 u8_t tcpstateflags; /**< Состояние и флаги TCP. */ 01168 u8_t timer; /**< Таймер ретрансмиссии. */ 01169 u8_t nrtx; /**< Количество ретрансмиссий, отправленных для 01170 последнего посланного сегмента. */ 01171 01172 /** Переменная состояния приложения. */ 01173 uip_tcp_appstate_t appstate; 01174 }; 01175 01176 01177 /** 01178 * Указатель на текущее соединение TCP. 01179 * 01180 * Указатель uip_conn может использоваться для доступа к текущему 01181 * соединению TCP. 01182 */ 01183 extern struct uip_conn *uip_conn; 01184 /* Массив, содержащий все соединения uIP. */ 01185 extern struct uip_conn uip_conns[UIP_CONNS]; 01186 /** 01187 * \addtogroup uiparch 01188 * @{ 01189 */ 01190 01191 /** 01192 * 4-байтовый массив для вычисления 32-битного номера последовательности. 01193 */ 01194 extern u8_t uip_acc32[4]; 01195 01196 /** @} */ 01197 01198 01199 #if UIP_UDP 01200 /** 01201 * Представление соединения UDP в стеке uIP. 01202 */ 01203 struct uip_udp_conn { 01204 uip_ipaddr_t ripaddr; /**< Адрес IP дальнего участника соединения. */ 01205 u16_t lport; /**< Локальный номер порта с сетевым порядком байт. */ 01206 u16_t rport; /**< Номер порта дальнего участника соединения, 01207 с сетевым порядком байт. */ 01208 u8_t ttl; /**< Время жизни по умолчанию (time-to-live). */ 01209 01210 /** Переменная состояния приложения. */ 01211 uip_udp_appstate_t appstate; 01212 }; 01213 01214 /** 01215 * Текущее соединение UDP. 01216 */ 01217 extern struct uip_udp_conn *uip_udp_conn; 01218 extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; 01219 #endif /* UIP_UDP */ 01220 01221 /** 01222 * Структура содержит статистику TCP/IP, которая собирается, если значение 01223 * UIP_STATISTICS установлено в 1. 01224 * 01225 */ 01226 struct uip_stats { 01227 struct { 01228 uip_stats_t drop; /**< Количество отброшенных пакетов на слое IP. */ 01229 uip_stats_t recv; /**< Количество принятых пакетов на слое IP. */ 01230 uip_stats_t sent; /**< Количество отправленных пакетов на слое IP. */ 01231 uip_stats_t vhlerr; /**< Количество отброшенных пакетов по причине 01232 ошибочной версии IP или длины заголовка. */ 01233 uip_stats_t hblenerr; /**< Количество отброшенных пакетов по причине 01234 ошибочной длины IP, старший байт. */ 01235 uip_stats_t lblenerr; /**< Количество отброшенных пакетов по причине 01236 ошибочной длины IP, младший байт. */ 01237 uip_stats_t fragerr; /**< Количество отброшенных пакетов по той причине, 01238 что они были IP-фрагментами. */ 01239 uip_stats_t chkerr; /**< Количество отброшенных пакетов из-за ошибок 01240 контрольной суммы IP. */ 01241 uip_stats_t protoerr; /**< Количество отброшенных пакетов по той причине, 01242 что не были пакетами ICMP, UDP или TCP. */ 01243 } ip; /**< Статистические данные IP. */ 01244 struct { 01245 uip_stats_t drop; /**< Количество отброшенных пакетов ICMP. */ 01246 uip_stats_t recv; /**< Количество принятых пакетов ICMP. */ 01247 uip_stats_t sent; /**< Количество отправленных пакетов ICMP. */ 01248 uip_stats_t typeerr; /**< Количество пакетов ICMP неправильного типа. */ 01249 } icmp; /**< Статистические данные ICMP. */ 01250 struct { 01251 uip_stats_t drop; /**< Количество отброшенных сегментов TCP. */ 01252 uip_stats_t recv; /**< Количество принятых сегментов TCP. */ 01253 uip_stats_t sent; /**< Количество отправленных сегментов TCP. */ 01254 uip_stats_t chkerr; /**< Количество сегментов TCP с ошибкой 01255 в контрольной сумме. */ 01256 uip_stats_t ackerr; /**< Количество сегментов TCP с ошибочным 01257 номером ACK. */ 01258 uip_stats_t rst; /**< Количество принятых сегментов TCP RST (сброс). */ 01259 uip_stats_t rexmit; /**< Количество повторно отправленных сегментов TCP. */ 01260 uip_stats_t syndrop; /**< Количество отброшенных SYN-ов из-за слишком малого 01261 количества доступных соединений. */ 01262 uip_stats_t synrst; /**< Количество SYN-ов для закрытых портов, 01263 инициировавших RST. */ 01264 } tcp; /**< Статистические данные TCP. */ 01265 #if UIP_UDP 01266 struct { 01267 uip_stats_t drop; /**< Количество отброшенных сегментов UDP. */ 01268 uip_stats_t recv; /**< Количество принятых сегментов UDP. */ 01269 uip_stats_t sent; /**< Количество отправленных сегментов UDP. */ 01270 uip_stats_t chkerr; /**< Количество сегментов UDP с ошибкой 01271 в контрольной сумме. */ 01272 } udp; /**< Статистические данные UDP. */ 01273 #endif /* UIP_UDP */ 01274 }; 01275 01276 /** 01277 * Статистическая инфрмация uIP TCP/IP. 01278 * 01279 * Это переменная, в которой собирается статистика uIP TCP/IP. 01280 */ 01281 extern struct uip_stats uip_stat; 01282 01283 01284 /*---------------------------------------------------------------------------*/ 01285 /* Все, что находится ниже этой точки, задействовано внутри uIP и не должно 01286 * использоваться напрямую в приложении или в драйвере устройства. 01287 */ 01288 /*---------------------------------------------------------------------------*/ 01289 /* u8_t uip_flags: 01290 * 01291 * Когда вызывается функция приложения, uip_flags будет содержать флаги, 01292 * которые заданы в этом файле. 01293 */ 01294 extern u8_t uip_flags; 01295 01296 /* Следующие флаги могут быть установлены в глобальной переменной uip_flags 01297 перед вызовом функции обратного вызова приложения (application callback). 01298 Флаги UIP_ACKDATA, UIP_NEWDATA и UIP_CLOSE могут быть установлены в одно 01299 и то же время, в то время как другие являются взаимоисключающими. 01300 Обратите внимание на то, что эти флаги *НЕ ДОЛЖНЫ* быть исползованы 01301 напрямую, в обход специальных макросов и функций uIP. */ 01302 01303 #define UIP_ACKDATA 1 /* Показывает, что переданные данные были 01304 подтверждены, и приложение может отправить 01305 новые данные вместо ретрансмиссии ранее 01306 отправленных. */ 01307 #define UIP_NEWDATA 2 /* Показывает, что дальний участник обмена 01308 отправил нам новые данные. */ 01309 #define UIP_REXMIT 4 /* Говорит приложению отправить заново данные, 01310 которые были отправлены последний раз. */ 01311 #define UIP_POLL 8 /* Используется для опроса приложения, чтобы 01312 проверить, есть ли у приложения данные, 01313 которые оно хотело бы отправить. */ 01314 #define UIP_CLOSE 16 /* Участник обмена (remote host) закрыл соединение, 01315 так что соединение завершилось. Или приложение 01316 сигнализирует, что оно хотело бы завершить 01317 соединение. */ 01318 #define UIP_ABORT 32 /* Участник обмена (remote host) оборвал соединение, 01319 так что соединение завершилось. Или приложение 01320 сигнализирует, что оно хотело бы оборвать 01321 соединение. */ 01322 #define UIP_CONNECTED 64 /* У нас есть соединение от remote host, и для него 01323 установлено новое соединение, или активное соединение 01324 было успешно установлено. */ 01325 01326 #define UIP_TIMEDOUT 128 /* Соединение было оборвано (aborted) из-за слишком 01327 большого количества повторных передач. */ 01328 01329 /* uip_process(flag): 01330 * 01331 * Действительная функция uIP, которая делает всю работу. 01332 */ 01333 void uip_process(u8_t flag); 01334 01335 /* Следующие флаги передаются в качестве аргумента для функции uip_process(). 01336 Они используются для того, чтобы отличить друг от друга два случая вызова 01337 uip_process(). Вызов может быть либо по причине наличия принятых данных, 01338 которые должны быть обработаны, либо потому, что сработал периодический 01339 таймер. Эти значения никогда не должны использоваться напрямую, только 01340 в макросах, которые определены в этом файле. */ 01341 01342 #define UIP_DATA 1 /* Говорит для uIP, что в буфере uip_buf 01343 есть поступившие данные. Длина данных 01344 сохранена в глобальной переменной uip_len. */ 01345 #define UIP_TIMER 2 /* Говорит для uIP, что сработал периодический 01346 таймер. */ 01347 #define UIP_POLL_REQUEST 3 /* Говорит для uIP, что должно быть опрошено 01348 соединение. */ 01349 #define UIP_UDP_SEND_CONN 4 /* Говорит для uIP, что в буфере uip_buf 01350 должна быть создана датаграмма UDP. */ 01351 #if UIP_UDP 01352 #define UIP_UDP_TIMER 5 01353 #endif /* UIP_UDP */ 01354 01355 /* Состояния TCP, используемые в uip_conn->tcpstateflags. */ 01356 #define UIP_CLOSED 0 01357 #define UIP_SYN_RCVD 1 01358 #define UIP_SYN_SENT 2 01359 #define UIP_ESTABLISHED 3 01360 #define UIP_FIN_WAIT_1 4 01361 #define UIP_FIN_WAIT_2 5 01362 #define UIP_CLOSING 6 01363 #define UIP_TIME_WAIT 7 01364 #define UIP_LAST_ACK 8 01365 #define UIP_TS_MASK 15 01366 01367 #define UIP_STOPPED 16 01368 01369 /* Заголовки TCP и IP. */ 01370 struct uip_tcpip_hdr { 01371 #if UIP_CONF_IPV6 01372 /* Заголовок IPv6. */ 01373 u8_t vtc, 01374 tcflow; 01375 u16_t flow; 01376 u8_t len[2]; 01377 u8_t proto, ttl; 01378 uip_ip6addr_t srcipaddr, destipaddr; 01379 #else /* UIP_CONF_IPV6 */ 01380 /* Заголовок IPv4. */ 01381 u8_t vhl, 01382 tos, 01383 len[2], 01384 ipid[2], 01385 ipoffset[2], 01386 ttl, 01387 proto; 01388 u16_t ipchksum; 01389 u16_t srcipaddr[2], 01390 destipaddr[2]; 01391 #endif /* UIP_CONF_IPV6 */ 01392 01393 /* Заголовок TCP. */ 01394 u16_t srcport, 01395 destport; 01396 u8_t seqno[4], 01397 ackno[4], 01398 tcpoffset, 01399 flags, 01400 wnd[2]; 01401 u16_t tcpchksum; 01402 u8_t urgp[2]; 01403 u8_t optdata[4]; 01404 }; 01405 01406 /* Заголовки ICMP и IP. */ 01407 struct uip_icmpip_hdr { 01408 #if UIP_CONF_IPV6 01409 /* Заголовок IPv6. */ 01410 u8_t vtc, 01411 tcf; 01412 u16_t flow; 01413 u8_t len[2]; 01414 u8_t proto, ttl; 01415 uip_ip6addr_t srcipaddr, destipaddr; 01416 #else /* UIP_CONF_IPV6 */ 01417 /* Заголовок IPv4. */ 01418 u8_t vhl, 01419 tos, 01420 len[2], 01421 ipid[2], 01422 ipoffset[2], 01423 ttl, 01424 proto; 01425 u16_t ipchksum; 01426 u16_t srcipaddr[2], 01427 destipaddr[2]; 01428 #endif /* UIP_CONF_IPV6 */ 01429 01430 /* Заголовок ICMP (echo). */ 01431 u8_t type, icode; 01432 u16_t icmpchksum; 01433 #if !UIP_CONF_IPV6 01434 u16_t id, seqno; 01435 #else /* !UIP_CONF_IPV6 */ 01436 u8_t flags, reserved1, reserved2, reserved3; 01437 u8_t icmp6data[16]; 01438 u8_t options[1]; 01439 #endif /* !UIP_CONF_IPV6 */ 01440 }; 01441 01442 01443 /* Заголовки UDP и IP. */ 01444 struct uip_udpip_hdr { 01445 #if UIP_CONF_IPV6 01446 /* Заголовок IPv6. */ 01447 u8_t vtc, 01448 tcf; 01449 u16_t flow; 01450 u8_t len[2]; 01451 u8_t proto, ttl; 01452 uip_ip6addr_t srcipaddr, destipaddr; 01453 #else /* UIP_CONF_IPV6 */ 01454 /* Заголовок IP. */ 01455 u8_t vhl, 01456 tos, 01457 len[2], 01458 ipid[2], 01459 ipoffset[2], 01460 ttl, 01461 proto; 01462 u16_t ipchksum; 01463 u16_t srcipaddr[2], 01464 destipaddr[2]; 01465 #endif /* UIP_CONF_IPV6 */ 01466 01467 /* Заголовок UDP. */ 01468 u16_t srcport, 01469 destport; 01470 u16_t udplen; 01471 u16_t udpchksum; 01472 }; 01473 01474 01475 01476 /** 01477 * Размер пространства, доступного для данных пользователей в буфере \ref uip_buf. 01478 * 01479 * Этот макрос содержит доступное место для данных пользователя в буфере \ref 01480 * uip_buf. Макрос предназначен для проверки границ доступных для пользователя данных. 01481 * 01482 * Пример: 01483 \code 01484 snprintf(uip_appdata, UIP_APPDATA_SIZE, "%u\n", i); 01485 \endcode 01486 * 01487 * \hideinitializer 01488 */ 01489 #define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) 01490 01491 01492 #define UIP_PROTO_ICMP 1 01493 #define UIP_PROTO_TCP 6 01494 #define UIP_PROTO_UDP 17 01495 #define UIP_PROTO_ICMP6 58 01496 01497 /* Размеры для заголовков. */ 01498 #if UIP_CONF_IPV6 01499 #define UIP_IPH_LEN 40 01500 #else /* UIP_CONF_IPV6 */ 01501 #define UIP_IPH_LEN 20 /* Размер заголовка IP */ 01502 #endif /* UIP_CONF_IPV6 */ 01503 #define UIP_UDPH_LEN 8 /* Размер заголовка UDP */ 01504 #define UIP_TCPH_LEN 20 /* Размер заголовка TCP */ 01505 #define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN) /* Размер для 01506 заголовка IP + UDP */ 01507 #define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN) /* Размер для 01508 заголовка IP + TCP */ 01509 #define UIP_TCPIP_HLEN UIP_IPTCPH_LEN 01510 01511 01512 #if UIP_FIXEDADDR 01513 extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr; 01514 #else /* UIP_FIXEDADDR */ 01515 extern uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr; 01516 #endif /* UIP_FIXEDADDR */ 01517 01518 01519 01520 /** 01521 * Представление 48-битного адреса Ethernet. 01522 */ 01523 struct uip_eth_addr { 01524 u8_t addr[6]; 01525 }; 01526 01527 /** 01528 * Вычисление контрольной суммы Internet для данных буфера. 01529 * 01530 * Контрольная сумма Internet - это поразрядное дополнение до 1 01531 * суммы поразрядного дополнения всех 16-битных слов в буфере. 01532 * 01533 * См. RFC1071. 01534 * 01535 * \param buf Указатель на буфер, от которого вычисляется контрольная 01536 * сумма. 01537 * 01538 * \param len Длина буфера, от которого вычисляется контрольная 01539 * сумма. 01540 * 01541 * \return The Контрольная сумма Internet для буфера. 01542 */ 01543 u16_t uip_chksum(u16_t *buf, u16_t len); 01544 01545 /** 01546 * Вычисление контрольной суммы заголовка IP для заголовка пакета 01547 * в буфере uip_buf. 01548 * 01549 * Контрольная сумма заголовка IP является контрольной суммой Internet 01550 * от 20 байт заголовка IP. 01551 * 01552 * \return Контрольная сумма заголовка IP для заголовка IP в 01553 * в буфере uip_buf. 01554 */ 01555 u16_t uip_ipchksum(void); 01556 01557 /** 01558 * Вычисление контрольной суммы TCP для пакета в uip_buf и uip_appdata. 01559 * 01560 * Контрольная сумма TCP является контрольной суммой Internet от содержимого 01561 * данных сегмента TCP, и псевдозаголовка, определенного в RFC793. 01562 * 01563 * \return Контрольная сумма TCP сегмента TCP в uip_buf, на который 01564 * указывает uip_appdata. 01565 */ 01566 u16_t uip_tcpchksum(void); 01567 01568 /** 01569 * Вычисление контрольной суммы UDP для пакета в uip_buf и uip_appdata. 01570 * 01571 * Контрольная сумма UDP является контрольной суммой Internet от содержимого 01572 * данных сегмента UDP, и псевдозаголовка, определенного в RFC768. 01573 * 01574 * \return Контрольная сумма UDP сегмента UDP segment в uip_buf, на который 01575 * указывает uip_appdata. 01576 */ 01577 u16_t uip_udpchksum(void); 01578 01579 01580 #endif /* __UIP_H__ */ 01581 01582 01583 /** @} */