/*------------------------------------------------------------------------------*/ u8_t uip_fw_forward(void) { struct fwcache_entry *fw; /* First check if the packet is destined for ourselves and return 0 to indicate that the packet should be processed locally. */ if(BUF->destipaddr[0] == uip_hostaddr[0] && BUF->destipaddr[1] == uip_hostaddr[1]) { return UIP_FW_LOCAL; } /* If we use ping IP address configuration, and our IP address is not yet configured, we should intercept all ICMP echo packets. */ #if UIP_PINGADDRCONF if((uip_hostaddr[0] | uip_hostaddr[1]) == 0 && BUF->proto == UIP_PROTO_ICMP && ICMPBUF->type == ICMP_ECHO) { return UIP_FW_LOCAL; } #endif /* UIP_PINGADDRCONF */ /* Check if the packet is in the forwarding cache already, and if so we drop it. */ for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) { if(fw->timer != 0 && #if UIP_REASSEMBLY > 0 fw->len == BUF->len && fw->offset == BUF->ipoffset && #endif fw->ipid == BUF->ipid && fw->srcipaddr[0] == BUF->srcipaddr[0] && fw->srcipaddr[1] == BUF->srcipaddr[1] && fw->destipaddr[0] == BUF->destipaddr[0] && fw->destipaddr[1] == BUF->destipaddr[1] && #if notdef fw->payload[0] == BUF->srcport && fw->payload[1] == BUF->destport && #endif fw->proto == BUF->proto) { /* Drop packet. */ return UIP_FW_FORWARDED; } } /* If the TTL reaches zero we produce an ICMP time exceeded message in the uip_buf buffer and forward that packet back to the sender of the packet. */ if(BUF->ttl <= 1) { /* No time exceeded for broadcasts and multicasts! */ if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) { return UIP_FW_LOCAL; } time_exceeded(); } /* Decrement the TTL (time-to-live) value in the IP header */ BUF->ttl = BUF->ttl - 1; /* Update the IP checksum. */ if(BUF->ipchksum >= HTONS(0xffff - 0x0100)) { BUF->ipchksum = BUF->ipchksum + HTONS(0x0100) + 1; } else { BUF->ipchksum = BUF->ipchksum + HTONS(0x0100); } if(uip_len > 0) { uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]; uip_fw_output(); } #if UIP_BROADCAST if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) { return UIP_FW_LOCAL; } #endif /* UIP_BROADCAST */ /* Return non-zero to indicate that the packet was forwarded and that no other processing should be made. */ return UIP_FW_FORWARDED; }
/*-----------------------------------------------------------------------------*/ void uip_split_output(void) { u16_t tcplen, len1, len2; /* We only try to split maximum sized TCP segments. */ if(BUF->proto == UIP_PROTO_TCP && uip_len == UIP_BUFSIZE - UIP_LLH_LEN) { tcplen = uip_len - UIP_TCPIP_HLEN; /* Split the segment in two. If the original packet length was odd, we make the second packet one byte larger. */ len1 = len2 = tcplen / 2; if(len1 + len2 < tcplen) { ++len2; } /* Create the first packet. This is done by altering the length field of the IP header and updating the checksums. */ uip_len = len1 + UIP_TCPIP_HLEN; #if UIP_CONF_IPV6 /* For IPv6, the IP length field does not include the IPv6 IP header length. */ BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); #else /* UIP_CONF_IPV6 */ BUF->len[0] = uip_len >> 8; BUF->len[1] = uip_len & 0xff; #endif /* UIP_CONF_IPV6 */ /* Recalculate the TCP checksum. */ BUF->tcpchksum = 0; BUF->tcpchksum = ~(uip_tcpchksum()); #if !UIP_CONF_IPV6 /* Recalculate the IP checksum. */ BUF->ipchksum = 0; BUF->ipchksum = ~(uip_ipchksum()); #endif /* UIP_CONF_IPV6 */ /* Transmit the first packet. */ uip_fw_output(); // tcpip_output(); /* Now, create the second packet. To do this, it is not enough to just alter the length field, but we must also update the TCP sequence number and point the uip_appdata to a new place in memory. This place is detemined by the length of the first packet (len1). */ uip_len = len2 + UIP_TCPIP_HLEN; #if UIP_CONF_IPV6 /* For IPv6, the IP length field does not include the IPv6 IP header length. */ BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); #else /* UIP_CONF_IPV6 */ BUF->len[0] = uip_len >> 8; BUF->len[1] = uip_len & 0xff; #endif /* UIP_CONF_IPV6 */ /* uip_appdata += len1;*/ memcpy(uip_appdata, (u8_t *)uip_appdata + len1, len2); uip_add32(BUF->seqno, len1); BUF->seqno[0] = uip_acc32[0]; BUF->seqno[1] = uip_acc32[1]; BUF->seqno[2] = uip_acc32[2]; BUF->seqno[3] = uip_acc32[3]; /* Recalculate the TCP checksum. */ BUF->tcpchksum = 0; BUF->tcpchksum = ~(uip_tcpchksum()); #if !UIP_CONF_IPV6 /* Recalculate the IP checksum. */ BUF->ipchksum = 0; BUF->ipchksum = ~(uip_ipchksum()); #endif /* UIP_CONF_IPV6 */ /* Transmit the second packet. */ uip_fw_output(); // tcpip_output(); } else {