uIP 1.0
|
00001 /* 00002 * Copyright (c) 2004, Swedish Institute of Computer Science. 00003 * Все права зарезервированы. * 00004 * Повторное распространение, использование в исходном и двоичном виде, 00005 * с модификацией или без - разрешается, если выполняются следующие 00006 * условия: 00007 * 1. Распространение исходного кода должно сохранить вышеуказанную пометку 00008 * копирайта, этот список условий и следующую правовую оговорку. 00009 * 2. Распространение исходного кода должно сохранить вышеуказанную пометку 00010 * копирайта, этот список условий и следующую правовую оговорку в 00011 * документации и/или других материалах, которые будут предоставлены 00012 * вместе с распространяемыми материалами. 00013 * 3. Имя автора не может использоваться, чтобы подтвердить или продвинуть 00014 * продукты, написанные с использованием этого программного обеспечения 00015 * без специального на то разрешения. 00016 * 00017 * ЭТО ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ АВТОРОМ ``КАК ЕСТЬ'', БЕЗ 00018 * КАКОЙ-ЛИБО ЛЮБОЙ РАСШИРЕННОЙ ИЛИ ПОДРАЗУМЕВАЕМОЙ ГАРАНТИИ, ВКЛЮЧАЯ, 00019 * НО НЕ ОГРАНИЧИВАЯСЬ ЭТИМ, ГАРАНТИИ ВЫСОКОГО СПРОСА И ПРИГОДНОСТИ 00020 * ДЛЯ КОНКРЕТНОЙ ЦЕЛИ. АВТОР НИ ПРИ КАКИХ УСЛОВИЯХ НЕ ОТВЕТСТВЕНЕН 00021 * ЗА ЛЮБЫЕ УБЫТКИ - ПРЯМЫЕ, КОСВЕННЫЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ, ОБРАЗЦОВЫЕ 00022 * ИЛИ ПОСЛЕДОВАТЕЛЬНЫЕ (ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ЭТИМ, ТРЕБОВАНИЯ 00023 * ЗАМЕНЫ ТОВАРА ИЛИ СЕРВИСА; ПОТЕРИ ИСПОЛЬЗОВАНИЯ, ДАННЫХ ИЛИ ВЫГОДЫ; 00024 * ИЛИ ПРЕКРАЩЕНИЕ БИЗНЕСА), ОДНАКО ВЫЗВАННЫЕ ПО ЛЮБОЙ ТЕОРИИ ОТВЕТСТВЕННОСТИ, 00025 * ЛИБО В КОНТРАКТЕ, ПРЯМОЙ ОТВЕТСТВЕННОСТИ, ЛИБО В НАРУШЕНИИ ЗАКОННЫХ ПРАВ 00026 * (ВКЛЮЧАЯ ТАК ИЛИ ИНАЧЕ НЕБРЕЖНОСТЬ), ВОЗНИКАЮЩИЕ ВСЕГДА ИЗ ИСПОЛЬЗОВАНИЯ 00027 * ЭТОГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, ДАЖЕ ЕСЛИ БЫЛО ПРЕДУПРЕЖДЕНИЕ О ВОЗМОЖНОСТИ 00028 * ТАКОГО ПОВРЕЖДЕНИЯ. 00029 * 00030 * Этот файл является частью стека uIP TCP/IP. 00031 * 00032 * Author: Adam Dunkels <adam@sics.se> 00033 * 00034 * $Id: uip-split.c,v 1.2 2006/06/12 08:00:30 adam Exp $ 00035 */ 00036 00037 #include <string.h> 00038 00039 #include "uip-split.h" 00040 #include "uip.h" 00041 #include "uip-fw.h" 00042 #include "uip_arch.h" 00043 00044 00045 00046 #define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) 00047 00048 /*-----------------------------------------------------------------------------*/ 00049 void 00050 uip_split_output(void) 00051 { 00052 u16_t tcplen, len1, len2; 00053 00054 /* Будем пытаться разбить только сегменты TCP максимального размера. */ 00055 if(BUF->proto == UIP_PROTO_TCP && 00056 uip_len == UIP_BUFSIZE - UIP_LLH_LEN) { 00057 00058 tcplen = uip_len - UIP_TCPIP_HLEN; 00059 /* Разделение сегмента на 2 частиo. Если длина оригинального пакета была 00060 нечетной, то второй пакет сделаем на 1 байт больше. */ 00061 len1 = len2 = tcplen / 2; 00062 if(len1 + len2 < tcplen) { 00063 ++len2; 00064 } 00065 00066 /* Создание первого пакета. Это делается изменением поля длины 00067 заголовка IP и обновлением контрольных сумм. */ 00068 uip_len = len1 + UIP_TCPIP_HLEN; 00069 #if UIP_CONF_IPV6 00070 /* Для IPv6 длина поля IP не включает длину IP заголовка IPv6. */ 00071 BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); 00072 BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); 00073 #else /* UIP_CONF_IPV6 */ 00074 BUF->len[0] = uip_len >> 8; 00075 BUF->len[1] = uip_len & 0xff; 00076 #endif /* UIP_CONF_IPV6 */ 00077 00078 /* Пересчет контрольной суммы TCP. */ 00079 BUF->tcpchksum = 0; 00080 BUF->tcpchksum = ~(uip_tcpchksum()); 00081 00082 #if !UIP_CONF_IPV6 00083 /* Пересчет контрольной суммы IP. */ 00084 BUF->ipchksum = 0; 00085 BUF->ipchksum = ~(uip_ipchksum()); 00086 #endif /* UIP_CONF_IPV6 */ 00087 00088 /* Передача первого пакета. */ 00089 /* uip_fw_output();*/ 00090 tcpip_output(); 00091 00092 /* Теперь создадим второй пакет. Чтобы это сделать, недостаточно 00093 просто поменять поле длины, нужно также обновить номер 00094 последовательности TCP и указать uip_appdata на новое место 00095 в памяти. Это место определяется из длины первого пакета (len1). */ 00096 uip_len = len2 + UIP_TCPIP_HLEN; 00097 #if UIP_CONF_IPV6 00098 /* Для IPv6 длина поля IP не включает длину IP заголовка IPv6. */ 00099 BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); 00100 BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); 00101 #else /* UIP_CONF_IPV6 */ 00102 BUF->len[0] = uip_len >> 8; 00103 BUF->len[1] = uip_len & 0xff; 00104 #endif /* UIP_CONF_IPV6 */ 00105 00106 /* uip_appdata += len1;*/ 00107 memcpy(uip_appdata, (u8_t *)uip_appdata + len1, len2); 00108 00109 uip_add32(BUF->seqno, len1); 00110 BUF->seqno[0] = uip_acc32[0]; 00111 BUF->seqno[1] = uip_acc32[1]; 00112 BUF->seqno[2] = uip_acc32[2]; 00113 BUF->seqno[3] = uip_acc32[3]; 00114 00115 /* Пересчет контрольной суммы TCP. */ 00116 BUF->tcpchksum = 0; 00117 BUF->tcpchksum = ~(uip_tcpchksum()); 00118 00119 #if !UIP_CONF_IPV6 00120 /* Пересчет контрольной суммы IP. */ 00121 BUF->ipchksum = 0; 00122 BUF->ipchksum = ~(uip_ipchksum()); 00123 #endif /* UIP_CONF_IPV6 */ 00124 00125 /* Передача второго пакета. */ 00126 /* uip_fw_output();*/ 00127 tcpip_output(); 00128 } else { 00129 /* uip_fw_output();*/ 00130 tcpip_output(); 00131 } 00132 00133 } 00134 /*-----------------------------------------------------------------------------*/