+++ /dev/null
-/**
- * @file
- * Functions common to all TCP/IPv4 modules, such as the byte order functions.
- *
- */
-
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * This file is part of the lwIP TCP/IP stack.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-
-#include "lwip/opt.h"
-
-#include "lwip/inet.h"
-
+++ /dev/null
-/**
- * @file
- * Incluse internet checksum functions.
- *
- */
-
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * This file is part of the lwIP TCP/IP stack.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-
-#include "lwip/opt.h"
-
-#include "lwip/inet_chksum.h"
-#include "lwip/def.h"
-
-#include <stddef.h>
-#include <string.h>
-
-/* These are some reference implementations of the checksum algorithm, with the
- * aim of being simple, correct and fully portable. Checksumming is the
- * first thing you would want to optimize for your platform. If you create
- * your own version, link it in and in your cc.h put:
- *
- * #define LWIP_CHKSUM <your_checksum_routine>
- *
- * Or you can select from the implementations below by defining
- * LWIP_CHKSUM_ALGORITHM to 1, 2 or 3.
- */
-
-#ifndef LWIP_CHKSUM
-# define LWIP_CHKSUM lwip_standard_chksum
-# ifndef LWIP_CHKSUM_ALGORITHM
-# define LWIP_CHKSUM_ALGORITHM 2
-# endif
-#endif
-/* If none set: */
-#ifndef LWIP_CHKSUM_ALGORITHM
-# define LWIP_CHKSUM_ALGORITHM 0
-#endif
-
-#if (LWIP_CHKSUM_ALGORITHM == 1) /* Version #1 */
-/**
- * lwip checksum
- *
- * @param dataptr points to start of data to be summed at any boundary
- * @param len length of data to be summed
- * @return host order (!) lwip checksum (non-inverted Internet sum)
- *
- * @note accumulator size limits summable length to 64k
- * @note host endianess is irrelevant (p3 RFC1071)
- */
-static u16_t
-lwip_standard_chksum(void *dataptr, u16_t len)
-{
- u32_t acc;
- u16_t src;
- u8_t *octetptr;
-
- acc = 0;
- /* dataptr may be at odd or even addresses */
- octetptr = (u8_t*)dataptr;
- while (len > 1) {
- /* declare first octet as most significant
- thus assume network order, ignoring host order */
- src = (*octetptr) << 8;
- octetptr++;
- /* declare second octet as least significant */
- src |= (*octetptr);
- octetptr++;
- acc += src;
- len -= 2;
- }
- if (len > 0) {
- /* accumulate remaining octet */
- src = (*octetptr) << 8;
- acc += src;
- }
- /* add deferred carry bits */
- acc = (acc >> 16) + (acc & 0x0000ffffUL);
- if ((acc & 0xffff0000UL) != 0) {
- acc = (acc >> 16) + (acc & 0x0000ffffUL);
- }
- /* This maybe a little confusing: reorder sum using htons()
- instead of ntohs() since it has a little less call overhead.
- The caller must invert bits for Internet sum ! */
- return htons((u16_t)acc);
-}
-#endif
-
-#if (LWIP_CHKSUM_ALGORITHM == 2) /* Alternative version #2 */
-/*
- * Curt McDowell
- * Broadcom Corp.
- * csm@broadcom.com
- *
- * IP checksum two bytes at a time with support for
- * unaligned buffer.
- * Works for len up to and including 0x20000.
- * by Curt McDowell, Broadcom Corp. 12/08/2005
- *
- * @param dataptr points to start of data to be summed at any boundary
- * @param len length of data to be summed
- * @return host order (!) lwip checksum (non-inverted Internet sum)
- */
-
-static u16_t
-lwip_standard_chksum(void *dataptr, int len)
-{
- u8_t *pb = (u8_t *)dataptr;
- u16_t *ps, t = 0;
- u32_t sum = 0;
- int odd = ((mem_ptr_t)pb & 1);
-
- /* Get aligned to u16_t */
- if (odd && len > 0) {
- ((u8_t *)&t)[1] = *pb++;
- len--;
- }
-
- /* Add the bulk of the data */
- ps = (u16_t *)(void *)pb;
- while (len > 1) {
- sum += *ps++;
- len -= 2;
- }
-
- /* Consume left-over byte, if any */
- if (len > 0) {
- ((u8_t *)&t)[0] = *(u8_t *)ps;
- }
-
- /* Add end bytes */
- sum += t;
-
- /* Fold 32-bit sum to 16 bits
- calling this twice is propably faster than if statements... */
- sum = FOLD_U32T(sum);
- sum = FOLD_U32T(sum);
-
- /* Swap if alignment was odd */
- if (odd) {
- sum = SWAP_BYTES_IN_WORD(sum);
- }
-
- return (u16_t)sum;
-}
-#endif
-
-#if (LWIP_CHKSUM_ALGORITHM == 3) /* Alternative version #3 */
-/**
- * An optimized checksum routine. Basically, it uses loop-unrolling on
- * the checksum loop, treating the head and tail bytes specially, whereas
- * the inner loop acts on 8 bytes at a time.
- *
- * @arg start of buffer to be checksummed. May be an odd byte address.
- * @len number of bytes in the buffer to be checksummed.
- * @return host order (!) lwip checksum (non-inverted Internet sum)
- *
- * by Curt McDowell, Broadcom Corp. December 8th, 2005
- */
-
-static u16_t
-lwip_standard_chksum(void *dataptr, int len)
-{
- u8_t *pb = (u8_t *)dataptr;
- u16_t *ps, t = 0;
- u32_t *pl;
- u32_t sum = 0, tmp;
- /* starts at odd byte address? */
- int odd = ((mem_ptr_t)pb & 1);
-
- if (odd && len > 0) {
- ((u8_t *)&t)[1] = *pb++;
- len--;
- }
-
- ps = (u16_t *)pb;
-
- if (((mem_ptr_t)ps & 3) && len > 1) {
- sum += *ps++;
- len -= 2;
- }
-
- pl = (u32_t *)ps;
-
- while (len > 7) {
- tmp = sum + *pl++; /* ping */
- if (tmp < sum) {
- tmp++; /* add back carry */
- }
-
- sum = tmp + *pl++; /* pong */
- if (sum < tmp) {
- sum++; /* add back carry */
- }
-
- len -= 8;
- }
-
- /* make room in upper bits */
- sum = FOLD_U32T(sum);
-
- ps = (u16_t *)pl;
-
- /* 16-bit aligned word remaining? */
- while (len > 1) {
- sum += *ps++;
- len -= 2;
- }
-
- /* dangling tail byte remaining? */
- if (len > 0) { /* include odd byte */
- ((u8_t *)&t)[0] = *(u8_t *)ps;
- }
-
- sum += t; /* add end bytes */
-
- /* Fold 32-bit sum to 16 bits
- calling this twice is propably faster than if statements... */
- sum = FOLD_U32T(sum);
- sum = FOLD_U32T(sum);
-
- if (odd) {
- sum = SWAP_BYTES_IN_WORD(sum);
- }
-
- return (u16_t)sum;
-}
-#endif
-
-/* inet_chksum_pseudo:
- *
- * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain.
- * IP addresses are expected to be in network byte order.
- *
- * @param p chain of pbufs over that a checksum should be calculated (ip data part)
- * @param src source ip address (used for checksum of pseudo header)
- * @param dst destination ip address (used for checksum of pseudo header)
- * @param proto ip protocol (used for checksum of pseudo header)
- * @param proto_len length of the ip data part (used for checksum of pseudo header)
- * @return checksum (as u16_t) to be saved directly in the protocol header
- */
-u16_t
-inet_chksum_pseudo(struct pbuf *p,
- ip_addr_t *src, ip_addr_t *dest,
- u8_t proto, u16_t proto_len)
-{
- u32_t acc;
- u32_t addr;
- struct pbuf *q;
- u8_t swapped;
-
- acc = 0;
- swapped = 0;
- /* iterate through all pbuf in chain */
- for(q = p; q != NULL; q = q->next) {
- LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n",
- (void *)q, (void *)q->next));
- acc += LWIP_CHKSUM(q->payload, q->len);
- /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/
- /* just executing this next line is probably faster that the if statement needed
- to check whether we really need to execute it, and does no harm */
- acc = FOLD_U32T(acc);
- if (q->len % 2 != 0) {
- swapped = 1 - swapped;
- acc = SWAP_BYTES_IN_WORD(acc);
- }
- /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/
- }
-
- if (swapped) {
- acc = SWAP_BYTES_IN_WORD(acc);
- }
- addr = ip4_addr_get_u32(src);
- acc += (addr & 0xffffUL);
- acc += ((addr >> 16) & 0xffffUL);
- addr = ip4_addr_get_u32(dest);
- acc += (addr & 0xffffUL);
- acc += ((addr >> 16) & 0xffffUL);
- acc += (u32_t)htons((u16_t)proto);
- acc += (u32_t)htons(proto_len);
-
- /* Fold 32-bit sum to 16 bits
- calling this twice is propably faster than if statements... */
- acc = FOLD_U32T(acc);
- acc = FOLD_U32T(acc);
- LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc));
- return (u16_t)~(acc & 0xffffUL);
-}
-
-/* inet_chksum_pseudo:
- *
- * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain.
- * IP addresses are expected to be in network byte order.
- *
- * @param p chain of pbufs over that a checksum should be calculated (ip data part)
- * @param src source ip address (used for checksum of pseudo header)
- * @param dst destination ip address (used for checksum of pseudo header)
- * @param proto ip protocol (used for checksum of pseudo header)
- * @param proto_len length of the ip data part (used for checksum of pseudo header)
- * @return checksum (as u16_t) to be saved directly in the protocol header
- */
-u16_t
-inet_chksum_pseudo_partial(struct pbuf *p,
- ip_addr_t *src, ip_addr_t *dest,
- u8_t proto, u16_t proto_len, u16_t chksum_len)
-{
- u32_t acc;
- u32_t addr;
- struct pbuf *q;
- u8_t swapped;
- u16_t chklen;
-
- acc = 0;
- swapped = 0;
- /* iterate through all pbuf in chain */
- for(q = p; (q != NULL) && (chksum_len > 0); q = q->next) {
- LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n",
- (void *)q, (void *)q->next));
- chklen = q->len;
- if (chklen > chksum_len) {
- chklen = chksum_len;
- }
- acc += LWIP_CHKSUM(q->payload, chklen);
- chksum_len -= chklen;
- LWIP_ASSERT("delete me", chksum_len < 0x7fff);
- /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/
- /* fold the upper bit down */
- acc = FOLD_U32T(acc);
- if (q->len % 2 != 0) {
- swapped = 1 - swapped;
- acc = SWAP_BYTES_IN_WORD(acc);
- }
- /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/
- }
-
- if (swapped) {
- acc = SWAP_BYTES_IN_WORD(acc);
- }
- addr = ip4_addr_get_u32(src);
- acc += (addr & 0xffffUL);
- acc += ((addr >> 16) & 0xffffUL);
- addr = ip4_addr_get_u32(dest);
- acc += (addr & 0xffffUL);
- acc += ((addr >> 16) & 0xffffUL);
- acc += (u32_t)htons((u16_t)proto);
- acc += (u32_t)htons(proto_len);
-
- /* Fold 32-bit sum to 16 bits
- calling this twice is propably faster than if statements... */
- acc = FOLD_U32T(acc);
- acc = FOLD_U32T(acc);
- LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc));
- return (u16_t)~(acc & 0xffffUL);
-}
-
-/* inet_chksum:
- *
- * Calculates the Internet checksum over a portion of memory. Used primarily for IP
- * and ICMP.
- *
- * @param dataptr start of the buffer to calculate the checksum (no alignment needed)
- * @param len length of the buffer to calculate the checksum
- * @return checksum (as u16_t) to be saved directly in the protocol header
- */
-
-u16_t
-inet_chksum(void *dataptr, u16_t len)
-{
- return ~LWIP_CHKSUM(dataptr, len);
-}
-
-/**
- * Calculate a checksum over a chain of pbufs (without pseudo-header, much like
- * inet_chksum only pbufs are used).
- *
- * @param p pbuf chain over that the checksum should be calculated
- * @return checksum (as u16_t) to be saved directly in the protocol header
- */
-u16_t
-inet_chksum_pbuf(struct pbuf *p)
-{
- u32_t acc;
- struct pbuf *q;
- u8_t swapped;
-
- acc = 0;
- swapped = 0;
- for(q = p; q != NULL; q = q->next) {
- acc += LWIP_CHKSUM(q->payload, q->len);
- acc = FOLD_U32T(acc);
- if (q->len % 2 != 0) {
- swapped = 1 - swapped;
- acc = SWAP_BYTES_IN_WORD(acc);
- }
- }
-
- if (swapped) {
- acc = SWAP_BYTES_IN_WORD(acc);
- }
- return (u16_t)~(acc & 0xffffUL);
-}
-
-/* These are some implementations for LWIP_CHKSUM_COPY, which copies data
- * like MEMCPY but generates a checksum at the same time. Since this is a
- * performance-sensitive function, you might want to create your own version
- * in assembly targeted at your hardware by defining it in lwipopts.h:
- * #define LWIP_CHKSUM_COPY(dst, src, len) your_chksum_copy(dst, src, len)
- */
-
-#if (LWIP_CHKSUM_COPY_ALGORITHM == 1) /* Version #1 */
-/** Safe but slow: first call MEMCPY, then call LWIP_CHKSUM.
- * For architectures with big caches, data might still be in cache when
- * generating the checksum after copying.
- */
-u16_t
-lwip_chksum_copy(void *dst, const void *src, u16_t len)
-{
- MEMCPY(dst, src, len);
- return LWIP_CHKSUM(dst, len);
-}
-#endif /* (LWIP_CHKSUM_COPY_ALGORITHM == 1) */
+++ /dev/null
-/**
- * @file
- * This is the IPv4 layer implementation for incoming and outgoing IP traffic.
- *
- * @see ip_frag.c
- *
- */
-
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * This file is part of the lwIP TCP/IP stack.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-
-#include "lwip/opt.h"
-#include "lwip/ip.h"
-#include "lwip/def.h"
-#include "lwip/mem.h"
-#include "lwip/ip_frag.h"
-#include "lwip/inet_chksum.h"
-#include "lwip/netif.h"
-#include "lwip/icmp.h"
-#include "lwip/igmp.h"
-#include "lwip/raw.h"
-#include "lwip/udp.h"
-#include "lwip/tcp_impl.h"
-#include "lwip/snmp.h"
-#include "lwip/dhcp.h"
-#include "lwip/autoip.h"
-#include "lwip/stats.h"
-#include "arch/perf.h"
-
-#include <string.h>
-
-/** Set this to 0 in the rare case of wanting to call an extra function to
- * generate the IP checksum (in contrast to calculating it on-the-fly). */
-#ifndef LWIP_INLINE_IP_CHKSUM
-#define LWIP_INLINE_IP_CHKSUM 1
-#endif
-#if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP
-#define CHECKSUM_GEN_IP_INLINE 1
-#else
-#define CHECKSUM_GEN_IP_INLINE 0
-#endif
-
-/**
- * The interface that provided the packet for the current callback
- * invocation.
- */
-struct netif *current_netif;
-
-/**
- * Header of the input packet currently being processed.
- */
-const struct ip_hdr *current_header;
-
-/**
- * Finds the appropriate network interface for a given IP address. It
- * searches the list of network interfaces linearly. A match is found
- * if the masked IP address of the network interface equals the masked
- * IP address given to the function.
- *
- * @param dest the destination IP address for which to find the route
- * @return the netif on which to send to reach dest
- */
-struct netif *
-ip_route(ip_addr_t *dest)
-{
- struct netif *netif;
-
- /* iterate through netifs */
- for(netif = netif_list; netif != NULL; netif = netif->next) {
- /* network mask matches? */
- if (netif_is_up(netif)) {
- if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
- /* return netif on which to forward IP packet */
- return netif;
- }
- }
- }
- if ((netif_default == NULL) || (!netif_is_up(netif_default))) {
- LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
- ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
- IP_STATS_INC(ip.rterr);
- snmp_inc_ipoutnoroutes();
- return NULL;
- }
- /* no matching netif found, use default netif */
- return netif_default;
-}
-
-#if IP_FORWARD
-/**
- * Forwards an IP packet. It finds an appropriate route for the
- * packet, decrements the TTL value of the packet, adjusts the
- * checksum and outputs the packet on the appropriate interface.
- *
- * @param p the packet to forward (p->payload points to IP header)
- * @param iphdr the IP header of the input packet
- * @param inp the netif on which this packet was received
- * @return the netif on which the packet was sent (NULL if it wasn't sent)
- */
-static struct netif *
-ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
-{
- struct netif *netif;
- ip_addr_t dest;
-
- PERF_START;
- dest = iphdr->dest;
-
- /* RFC3927 2.7: do not forward link-local addresses */
- if (ip_addr_islinklocal(&dest)) {
- LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
- ip4_addr1_16(&dest), ip4_addr2_16(&dest), ip4_addr3_16(&dest), ip4_addr4_16(&dest)));
- snmp_inc_ipoutnoroutes();
- return (struct netif *)NULL;
- }
-
- /* Find network interface where to forward this IP packet to. */
- netif = ip_route(&dest);
- if (netif == NULL) {
- LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n",
- ip4_addr1_16(&dest), ip4_addr2_16(&dest), ip4_addr3_16(&dest), ip4_addr4_16(&dest)));
- snmp_inc_ipoutnoroutes();
- return (struct netif *)NULL;
- }
- /* Do not forward packets onto the same network interface on which
- * they arrived. */
- if (netif == inp) {
- LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));
- snmp_inc_ipoutnoroutes();
- return (struct netif *)NULL;
- }
-
- /* decrement TTL */
- IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
- /* send ICMP if TTL == 0 */
- if (IPH_TTL(iphdr) == 0) {
- snmp_inc_ipinhdrerrors();
-#if LWIP_ICMP
- /* Don't send ICMP messages in response to ICMP messages */
- if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) {
- icmp_time_exceeded(p, ICMP_TE_TTL);
- }
-#endif /* LWIP_ICMP */
- return (struct netif *)NULL;
- }
-
- /* Incrementally update the IP checksum. */
- if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffff - 0x100)) {
- IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100) + 1);
- } else {
- IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100));
- }
-
- LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
- ip4_addr1_16(&dest), ip4_addr2_16(&dest), ip4_addr3_16(&dest), ip4_addr4_16(&dest)));
-
- IP_STATS_INC(ip.fw);
- IP_STATS_INC(ip.xmit);
- snmp_inc_ipforwdatagrams();
-
- PERF_STOP("ip_forward");
- /* transmit pbuf on chosen interface */
- netif->output(netif, p, &dest);
- return netif;
-}
-#endif /* IP_FORWARD */
-
-/**
- * This function is called by the network interface device driver when
- * an IP packet is received. The function does the basic checks of the
- * IP header such as packet size being at least larger than the header
- * size etc. If the packet was not destined for us, the packet is
- * forwarded (using ip_forward). The IP checksum is always checked.
- *
- * Finally, the packet is sent to the upper layer protocol input function.
- *
- * @param p the received IP packet (p->payload points to IP header)
- * @param inp the netif on which this packet was received
- * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't
- * processed, but currently always returns ERR_OK)
- */
-err_t
-ip_input(struct pbuf *p, struct netif *inp)
-{
- struct ip_hdr *iphdr;
- struct netif *netif;
- u16_t iphdr_hlen;
- u16_t iphdr_len;
-#if LWIP_DHCP
- int check_ip_src=1;
-#endif /* LWIP_DHCP */
-
- IP_STATS_INC(ip.recv);
- snmp_inc_ipinreceives();
-
- /* identify the IP header */
- iphdr = (struct ip_hdr *)p->payload;
- if (IPH_V(iphdr) != 4) {
- LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", IPH_V(iphdr)));
- ip_debug_print(p);
- pbuf_free(p);
- IP_STATS_INC(ip.err);
- IP_STATS_INC(ip.drop);
- snmp_inc_ipinhdrerrors();
- return ERR_OK;
- }
-
- /* obtain IP header length in number of 32-bit words */
- iphdr_hlen = IPH_HL(iphdr);
- /* calculate IP header length in bytes */
- iphdr_hlen *= 4;
- /* obtain ip length in bytes */
- iphdr_len = ntohs(IPH_LEN(iphdr));
-
- /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */
- if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len)) {
- if (iphdr_hlen > p->len) {
- LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
- ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n",
- iphdr_hlen, p->len));
- }
- if (iphdr_len > p->tot_len) {
- LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
- ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n",
- iphdr_len, p->tot_len));
- }
- /* free (drop) packet pbufs */
- pbuf_free(p);
- IP_STATS_INC(ip.lenerr);
- IP_STATS_INC(ip.drop);
- snmp_inc_ipindiscards();
- return ERR_OK;
- }
-
- /* verify checksum */
-#if CHECKSUM_CHECK_IP
- if (inet_chksum(iphdr, iphdr_hlen) != 0) {
-
- LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
- ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen)));
- ip_debug_print(p);
- pbuf_free(p);
- IP_STATS_INC(ip.chkerr);
- IP_STATS_INC(ip.drop);
- snmp_inc_ipinhdrerrors();
- return ERR_OK;
- }
-#endif
-
- /* Trim pbuf. This should have been done at the netif layer,
- * but we'll do it anyway just to be sure that its done. */
- pbuf_realloc(p, iphdr_len);
-
- /* match packet against an interface, i.e. is this packet for us? */
-#if LWIP_IGMP
- if (ip_addr_ismulticast(&(iphdr->dest))) {
- if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, &(iphdr->dest)))) {
- netif = inp;
- } else {
- netif = NULL;
- }
- } else
-#endif /* LWIP_IGMP */
- {
- /* start trying with inp. if that's not acceptable, start walking the
- list of configured netifs.
- 'first' is used as a boolean to mark whether we started walking the list */
- int first = 1;
- netif = inp;
- do {
- LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n",
- ip4_addr_get_u32(&iphdr->dest), ip4_addr_get_u32(&netif->ip_addr),
- ip4_addr_get_u32(&iphdr->dest) & ip4_addr_get_u32(&netif->netmask),
- ip4_addr_get_u32(&netif->ip_addr) & ip4_addr_get_u32(&netif->netmask),
- ip4_addr_get_u32(&iphdr->dest) & ~ip4_addr_get_u32(&netif->netmask)));
-
- /* interface is up and configured? */
- if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr)))) {
- /* unicast to this interface address? */
- if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||
- /* or broadcast on this interface network address? */
- ip_addr_isbroadcast(&(iphdr->dest), netif)) {
- LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",
- netif->name[0], netif->name[1]));
- /* break out of for loop */
- break;
- }
-#if LWIP_AUTOIP
- /* connections to link-local addresses must persist after changing
- the netif's address (RFC3927 ch. 1.9) */
- if ((netif->autoip != NULL) &&
- ip_addr_cmp(&(iphdr->dest), &(netif->autoip->llipaddr))) {
- LWIP_DEBUGF(IP_DEBUG, ("ip_input: LLA packet accepted on interface %c%c\n",
- netif->name[0], netif->name[1]));
- /* break out of for loop */
- break;
- }
-#endif /* LWIP_AUTOIP */
- }
- if (first) {
- first = 0;
- netif = netif_list;
- } else {
- netif = netif->next;
- }
- if (netif == inp) {
- netif = netif->next;
- }
- } while(netif != NULL);
- }
-
-#if LWIP_DHCP
- /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed
- * using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
- * According to RFC 1542 section 3.1.1, referred by RFC 2131).
- */
- if (netif == NULL) {
- /* remote port is DHCP server? */
- if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
- struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen);
- LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: UDP packet to DHCP client port %"U16_F"\n",
- ntohs(udphdr->dest)));
- if (udphdr->dest == PP_NTOHS(DHCP_CLIENT_PORT)) {
- LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: DHCP packet accepted.\n"));
- netif = inp;
- check_ip_src = 0;
- }
- }
- }
-#endif /* LWIP_DHCP */
-
- /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */
-#if LWIP_DHCP
- /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */
- if (check_ip_src && !ip_addr_isany(&iphdr->src))
-#endif /* LWIP_DHCP */
- { if ((ip_addr_isbroadcast(&(iphdr->src), inp)) ||
- (ip_addr_ismulticast(&(iphdr->src)))) {
- /* packet source is not valid */
- LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip_input: packet source is not valid.\n"));
- /* free (drop) packet pbufs */
- pbuf_free(p);
- IP_STATS_INC(ip.drop);
- snmp_inc_ipinaddrerrors();
- snmp_inc_ipindiscards();
- return ERR_OK;
- }
- }
-
- /* packet not for us? */
- if (netif == NULL) {
- /* packet not for us, route or discard */
- LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: packet not for us.\n"));
-#if IP_FORWARD
- /* non-broadcast packet? */
- if (!ip_addr_isbroadcast(&(iphdr->dest), inp)) {
- /* try to forward IP packet on (other) interfaces */
- ip_forward(p, iphdr, inp);
- } else
-#endif /* IP_FORWARD */
- {
- snmp_inc_ipinaddrerrors();
- snmp_inc_ipindiscards();
- }
- pbuf_free(p);
- return ERR_OK;
- }
- /* packet consists of multiple fragments? */
- if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) {
-#if IP_REASSEMBLY /* packet fragment reassembly code present? */
- LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip_reass()\n",
- ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));
- /* reassemble the packet*/
- p = ip_reass(p);
- /* packet not fully reassembled yet? */
- if (p == NULL) {
- return ERR_OK;
- }
- iphdr = (struct ip_hdr *)p->payload;
-#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */
- pbuf_free(p);
- LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n",
- ntohs(IPH_OFFSET(iphdr))));
- IP_STATS_INC(ip.opterr);
- IP_STATS_INC(ip.drop);
- /* unsupported protocol feature */
- snmp_inc_ipinunknownprotos();
- return ERR_OK;
-#endif /* IP_REASSEMBLY */
- }
-
-#if IP_OPTIONS_ALLOWED == 0 /* no support for IP options in the IP header? */
-
-#if LWIP_IGMP
- /* there is an extra "router alert" option in IGMP messages which we allow for but do not police */
- if((iphdr_hlen > IP_HLEN) && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) {
-#else
- if (iphdr_hlen > IP_HLEN) {
-#endif /* LWIP_IGMP */
- LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n"));
- pbuf_free(p);
- IP_STATS_INC(ip.opterr);
- IP_STATS_INC(ip.drop);
- /* unsupported protocol feature */
- snmp_inc_ipinunknownprotos();
- return ERR_OK;
- }
-#endif /* IP_OPTIONS_ALLOWED == 0 */
-
- /* send to upper layers */
- LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n"));
- ip_debug_print(p);
- LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));
-
- current_netif = inp;
- current_header = iphdr;
-
-#if LWIP_RAW
- /* raw input did not eat the packet? */
- if (raw_input(p, inp) == 0)
-#endif /* LWIP_RAW */
- {
-
- switch (IPH_PROTO(iphdr)) {
-#if LWIP_UDP
- case IP_PROTO_UDP:
-#if LWIP_UDPLITE
- case IP_PROTO_UDPLITE:
-#endif /* LWIP_UDPLITE */
- snmp_inc_ipindelivers();
- udp_input(p, inp);
- break;
-#endif /* LWIP_UDP */
-#if LWIP_TCP
- case IP_PROTO_TCP:
- snmp_inc_ipindelivers();
- tcp_input(p, inp);
- break;
-#endif /* LWIP_TCP */
-#if LWIP_ICMP
- case IP_PROTO_ICMP:
- snmp_inc_ipindelivers();
- icmp_input(p, inp);
- break;
-#endif /* LWIP_ICMP */
-#if LWIP_IGMP
- case IP_PROTO_IGMP:
- igmp_input(p,inp,&(iphdr->dest));
- break;
-#endif /* LWIP_IGMP */
- default:
-#if LWIP_ICMP
- /* send ICMP destination protocol unreachable unless is was a broadcast */
- if (!ip_addr_isbroadcast(&(iphdr->dest), inp) &&
- !ip_addr_ismulticast(&(iphdr->dest))) {
- p->payload = iphdr;
- icmp_dest_unreach(p, ICMP_DUR_PROTO);
- }
-#endif /* LWIP_ICMP */
- pbuf_free(p);
-
- LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", IPH_PROTO(iphdr)));
-
- IP_STATS_INC(ip.proterr);
- IP_STATS_INC(ip.drop);
- snmp_inc_ipinunknownprotos();
- }
- }
-
- current_netif = NULL;
- current_header = NULL;
-
- return ERR_OK;
-}
-
-/**
- * Sends an IP packet on a network interface. This function constructs
- * the IP header and calculates the IP header checksum. If the source
- * IP address is NULL, the IP address of the outgoing network
- * interface is filled in as source address.
- * If the destination IP address is IP_HDRINCL, p is assumed to already
- * include an IP header and p->payload points to it instead of the data.
- *
- * @param p the packet to send (p->payload points to the data, e.g. next
- protocol header; if dest == IP_HDRINCL, p already includes an IP
- header and p->payload points to that IP header)
- * @param src the source IP address to send from (if src == IP_ADDR_ANY, the
- * IP address of the netif used to send is used as source address)
- * @param dest the destination IP address to send the packet to
- * @param ttl the TTL value to be set in the IP header
- * @param tos the TOS value to be set in the IP header
- * @param proto the PROTOCOL to be set in the IP header
- * @param netif the netif on which to send this packet
- * @return ERR_OK if the packet was sent OK
- * ERR_BUF if p doesn't have enough space for IP/LINK headers
- * returns errors returned by netif->output
- *
- * @note ip_id: RFC791 "some host may be able to simply use
- * unique identifiers independent of destination"
- */
-err_t
-ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
- u8_t ttl, u8_t tos,
- u8_t proto, struct netif *netif)
-{
-#if IP_OPTIONS_SEND
- return ip_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0);
-}
-
-/**
- * Same as ip_output_if() but with the possibility to include IP options:
- *
- * @ param ip_options pointer to the IP options, copied into the IP header
- * @ param optlen length of ip_options
- */
-err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
- u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
- u16_t optlen)
-{
-#endif /* IP_OPTIONS_SEND */
- struct ip_hdr *iphdr;
- static u16_t ip_id = 0;
-#if CHECKSUM_GEN_IP_INLINE
- u32_t chk_sum;
-#endif /* CHECKSUM_GEN_IP_INLINE */
-
- /* pbufs passed to IP must have a ref-count of 1 as their payload pointer
- gets altered as the packet is passed down the stack */
- LWIP_ASSERT("p->ref == 1", p->ref == 1);
-
- snmp_inc_ipoutrequests();
-
- /* Should the IP header be generated or is it already included in p? */
- if (dest != IP_HDRINCL) {
- u16_t ip_hlen = IP_HLEN;
-#if IP_OPTIONS_SEND
- u16_t optlen_aligned = 0;
- if (optlen != 0) {
- /* round up to a multiple of 4 */
- optlen_aligned = ((optlen + 3) & ~3);
- ip_hlen += optlen_aligned;
- /* First write in the IP options */
- if (pbuf_header(p, optlen_aligned)) {
- LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output_if_opt: not enough room for IP options in pbuf\n"));
- IP_STATS_INC(ip.err);
- snmp_inc_ipoutdiscards();
- return ERR_BUF;
- }
- MEMCPY(p->payload, ip_options, optlen);
- if (optlen < optlen_aligned) {
- /* zero the remaining bytes */
- memset(((char*)p->payload) + optlen, 0, optlen_aligned - optlen);
- }
- }
-#endif /* IP_OPTIONS_SEND */
- /* generate IP header */
- if (pbuf_header(p, IP_HLEN)) {
- LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output: not enough room for IP header in pbuf\n"));
-
- IP_STATS_INC(ip.err);
- snmp_inc_ipoutdiscards();
- return ERR_BUF;
- }
-
- iphdr = (struct ip_hdr *)p->payload;
- LWIP_ASSERT("check that first pbuf can hold struct ip_hdr",
- (p->len >= sizeof(struct ip_hdr)));
-
- IPH_TTL_SET(iphdr, ttl);
- IPH_PROTO_SET(iphdr, proto);
-#if CHECKSUM_GEN_IP_INLINE
- chk_sum = LWIP_MAKE_U16(proto, ttl);
-#endif /* CHECKSUM_GEN_IP_INLINE */
-
- /* dest cannot be NULL here */
- ip_addr_copy(iphdr->dest, *dest);
-#if CHECKSUM_GEN_IP_INLINE
- chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF;
- chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16;
-#endif /* CHECKSUM_GEN_IP_INLINE */
-
- IPH_VHLTOS_SET(iphdr, 4, ip_hlen / 4, tos);
-#if CHECKSUM_GEN_IP_INLINE
- chk_sum += iphdr->_v_hl_tos;
-#endif /* CHECKSUM_GEN_IP_INLINE */
- IPH_LEN_SET(iphdr, htons(p->tot_len));
-#if CHECKSUM_GEN_IP_INLINE
- chk_sum += iphdr->_len;
-#endif /* CHECKSUM_GEN_IP_INLINE */
- IPH_OFFSET_SET(iphdr, 0);
- IPH_ID_SET(iphdr, htons(ip_id));
-#if CHECKSUM_GEN_IP_INLINE
- chk_sum += iphdr->_id;
-#endif /* CHECKSUM_GEN_IP_INLINE */
- ++ip_id;
-
- if (ip_addr_isany(src)) {
- ip_addr_copy(iphdr->src, netif->ip_addr);
- } else {
- /* src cannot be NULL here */
- ip_addr_copy(iphdr->src, *src);
- }
-
-#if CHECKSUM_GEN_IP_INLINE
- chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF;
- chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16;
- chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
- chk_sum = (chk_sum >> 16) + chk_sum;
- chk_sum = ~chk_sum;
- iphdr->_chksum = chk_sum; /* network order */
-#else /* CHECKSUM_GEN_IP_INLINE */
- IPH_CHKSUM_SET(iphdr, 0);
-#if CHECKSUM_GEN_IP
- IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen));
-#endif
-#endif /* CHECKSUM_GEN_IP_INLINE */
- } else {
- /* IP header already included in p */
- iphdr = (struct ip_hdr *)p->payload;
- dest = &(iphdr->dest);
- }
-
- IP_STATS_INC(ip.xmit);
-
- LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num));
- ip_debug_print(p);
-
-#if ENABLE_LOOPBACK
- if (ip_addr_cmp(dest, &netif->ip_addr)) {
- /* Packet to self, enqueue it for loopback */
- LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()"));
- return netif_loop_output(netif, p, dest);
- }
-#endif /* ENABLE_LOOPBACK */
-#if IP_FRAG
- /* don't fragment if interface has mtu set to 0 [loopif] */
- if (netif->mtu && (p->tot_len > netif->mtu)) {
- return ip_frag(p,netif,dest);
- }
-#endif
-
- LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));
- return netif->output(netif, p, dest);
-}
-
-/**
- * Simple interface to ip_output_if. It finds the outgoing network
- * interface and calls upon ip_output_if to do the actual work.
- *
- * @param p the packet to send (p->payload points to the data, e.g. next
- protocol header; if dest == IP_HDRINCL, p already includes an IP
- header and p->payload points to that IP header)
- * @param src the source IP address to send from (if src == IP_ADDR_ANY, the
- * IP address of the netif used to send is used as source address)
- * @param dest the destination IP address to send the packet to
- * @param ttl the TTL value to be set in the IP header
- * @param tos the TOS value to be set in the IP header
- * @param proto the PROTOCOL to be set in the IP header
- *
- * @return ERR_RTE if no route is found
- * see ip_output_if() for more return values
- */
-err_t
-ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
- u8_t ttl, u8_t tos, u8_t proto)
-{
- struct netif *netif;
-
- /* pbufs passed to IP must have a ref-count of 1 as their payload pointer
- gets altered as the packet is passed down the stack */
- LWIP_ASSERT("p->ref == 1", p->ref == 1);
-
- if ((netif = ip_route(dest)) == NULL) {
- LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
- ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
- IP_STATS_INC(ip.rterr);
- return ERR_RTE;
- }
-
- return ip_output_if(p, src, dest, ttl, tos, proto, netif);
-}
-
-#if LWIP_NETIF_HWADDRHINT
-/** Like ip_output, but takes and addr_hint pointer that is passed on to netif->addr_hint
- * before calling ip_output_if.
- *
- * @param p the packet to send (p->payload points to the data, e.g. next
- protocol header; if dest == IP_HDRINCL, p already includes an IP
- header and p->payload points to that IP header)
- * @param src the source IP address to send from (if src == IP_ADDR_ANY, the
- * IP address of the netif used to send is used as source address)
- * @param dest the destination IP address to send the packet to
- * @param ttl the TTL value to be set in the IP header
- * @param tos the TOS value to be set in the IP header
- * @param proto the PROTOCOL to be set in the IP header
- * @param addr_hint address hint pointer set to netif->addr_hint before
- * calling ip_output_if()
- *
- * @return ERR_RTE if no route is found
- * see ip_output_if() for more return values
- */
-err_t
-ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
- u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint)
-{
- struct netif *netif;
- err_t err;
-
- /* pbufs passed to IP must have a ref-count of 1 as their payload pointer
- gets altered as the packet is passed down the stack */
- LWIP_ASSERT("p->ref == 1", p->ref == 1);
-
- if ((netif = ip_route(dest)) == NULL) {
- LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
- ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
- IP_STATS_INC(ip.rterr);
- return ERR_RTE;
- }
-
- netif->addr_hint = addr_hint;
- err = ip_output_if(p, src, dest, ttl, tos, proto, netif);
- netif->addr_hint = NULL;
-
- return err;
-}
-#endif /* LWIP_NETIF_HWADDRHINT*/
-
-#if IP_DEBUG
-/* Print an IP header by using LWIP_DEBUGF
- * @param p an IP packet, p->payload pointing to the IP header
- */
-void
-ip_debug_print(struct pbuf *p)
-{
- struct ip_hdr *iphdr = (struct ip_hdr *)p->payload;
- u8_t *payload;
-
- payload = (u8_t *)iphdr + IP_HLEN;
-
- LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
- LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
- LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" | 0x%02"X16_F" | %5"U16_F" | (v, hl, tos, len)\n",
- IPH_V(iphdr),
- IPH_HL(iphdr),
- IPH_TOS(iphdr),
- ntohs(IPH_LEN(iphdr))));
- LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
- LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" |%"U16_F"%"U16_F"%"U16_F"| %4"U16_F" | (id, flags, offset)\n",
- ntohs(IPH_ID(iphdr)),
- ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,
- ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,
- ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,
- ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK));
- LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
- LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | 0x%04"X16_F" | (ttl, proto, chksum)\n",
- IPH_TTL(iphdr),
- IPH_PROTO(iphdr),
- ntohs(IPH_CHKSUM(iphdr))));
- LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
- LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (src)\n",
- ip4_addr1_16(&iphdr->src),
- ip4_addr2_16(&iphdr->src),
- ip4_addr3_16(&iphdr->src),
- ip4_addr4_16(&iphdr->src)));
- LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
- LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (dest)\n",
- ip4_addr1_16(&iphdr->dest),
- ip4_addr2_16(&iphdr->dest),
- ip4_addr3_16(&iphdr->dest),
- ip4_addr4_16(&iphdr->dest)));
- LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
-}
-#endif /* IP_DEBUG */
+++ /dev/null
-/**
- * @file
- * This is the IPv4 address tools implementation.
- *
- */
-
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * This file is part of the lwIP TCP/IP stack.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-
-#include "lwip/opt.h"
-#include "lwip/ip_addr.h"
-#include "lwip/netif.h"
-
-/* used by IP_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */
-const ip_addr_t ip_addr_any = { IPADDR_ANY };
-const ip_addr_t ip_addr_broadcast = { IPADDR_BROADCAST };
-
-/**
- * Determine if an address is a broadcast address on a network interface
- *
- * @param addr address to be checked
- * @param netif the network interface against which the address is checked
- * @return returns non-zero if the address is a broadcast address
- */
-u8_t ip_addr_isbroadcast(const ip_addr_t *addr, const struct netif *netif)
-{
- u32_t addr2test;
-
- addr2test = ip4_addr_get_u32(addr);
- /* all ones (broadcast) or all zeroes (old skool broadcast) */
- if ((~addr2test == IPADDR_ANY) ||
- (addr2test == IPADDR_ANY))
- return 1;
- /* no broadcast support on this network interface? */
- else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0)
- /* the given address cannot be a broadcast address
- * nor can we check against any broadcast addresses */
- return 0;
- /* address matches network interface address exactly? => no broadcast */
- else if (addr2test == ip4_addr_get_u32(&netif->ip_addr))
- return 0;
- /* on the same (sub) network... */
- else if (ip_addr_netcmp(addr, &(netif->ip_addr), &(netif->netmask))
- /* ...and host identifier bits are all ones? =>... */
- && ((addr2test & ~ip4_addr_get_u32(&netif->netmask)) ==
- (IPADDR_BROADCAST & ~ip4_addr_get_u32(&netif->netmask))))
- /* => network broadcast address */
- return 1;
- else
- return 0;
-}
-
-/* Here for now until needed in other places in lwIP */
-#ifndef isprint
-#define in_range(c, lo, up) ((u8_t)c >= lo && (u8_t)c <= up)
-#define isprint(c) in_range(c, 0x20, 0x7f)
-#define isdigit(c) in_range(c, '0', '9')
-#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F'))
-#define islower(c) in_range(c, 'a', 'z')
-#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')
-#endif
-
-/**
- * Ascii internet address interpretation routine.
- * The value returned is in network order.
- *
- * @param cp IP address in ascii represenation (e.g. "127.0.0.1")
- * @return ip address in network order
- */
-u32_t
-ipaddr_addr(const char *cp)
-{
- ip_addr_t val;
-
- if (ipaddr_aton(cp, &val)) {
- return ip4_addr_get_u32(&val);
- }
- return (IPADDR_NONE);
-}
-
-/**
- * Check whether "cp" is a valid ascii representation
- * of an Internet address and convert to a binary address.
- * Returns 1 if the address is valid, 0 if not.
- * This replaces inet_addr, the return value from which
- * cannot distinguish between failure and a local broadcast address.
- *
- * @param cp IP address in ascii represenation (e.g. "127.0.0.1")
- * @param addr pointer to which to save the ip address in network order
- * @return 1 if cp could be converted to addr, 0 on failure
- */
-int
-ipaddr_aton(const char *cp, ip_addr_t *addr)
-{
- u32_t val;
- u8_t base;
- char c;
- u32_t parts[4];
- u32_t *pp = parts;
-
- c = *cp;
- for (;;) {
- /*
- * Collect number up to ``.''.
- * Values are specified as for C:
- * 0x=hex, 0=octal, 1-9=decimal.
- */
- if (!isdigit(c))
- return (0);
- val = 0;
- base = 10;
- if (c == '0') {
- c = *++cp;
- if (c == 'x' || c == 'X') {
- base = 16;
- c = *++cp;
- } else
- base = 8;
- }
- for (;;) {
- if (isdigit(c)) {
- val = (val * base) + (int)(c - '0');
- c = *++cp;
- } else if (base == 16 && isxdigit(c)) {
- val = (val << 4) | (int)(c + 10 - (islower(c) ? 'a' : 'A'));
- c = *++cp;
- } else
- break;
- }
- if (c == '.') {
- /*
- * Internet format:
- * a.b.c.d
- * a.b.c (with c treated as 16 bits)
- * a.b (with b treated as 24 bits)
- */
- if (pp >= parts + 3) {
- return (0);
- }
- *pp++ = val;
- c = *++cp;
- } else
- break;
- }
- /*
- * Check for trailing characters.
- */
- if (c != '\0' && !isspace(c)) {
- return (0);
- }
- /*
- * Concoct the address according to
- * the number of parts specified.
- */
- switch (pp - parts + 1) {
-
- case 0:
- return (0); /* initial nondigit */
-
- case 1: /* a -- 32 bits */
- break;
-
- case 2: /* a.b -- 8.24 bits */
- if (val > 0xffffffUL) {
- return (0);
- }
- val |= parts[0] << 24;
- break;
-
- case 3: /* a.b.c -- 8.8.16 bits */
- if (val > 0xffff) {
- return (0);
- }
- val |= (parts[0] << 24) | (parts[1] << 16);
- break;
-
- case 4: /* a.b.c.d -- 8.8.8.8 bits */
- if (val > 0xff) {
- return (0);
- }
- val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
- break;
- default:
- LWIP_ASSERT("unhandled", 0);
- break;
- }
- if (addr) {
- ip4_addr_set_u32(addr, htonl(val));
- }
- return (1);
-}
-
-/**
- * Convert numeric IP address into decimal dotted ASCII representation.
- * returns ptr to static buffer; not reentrant!
- *
- * @param addr ip address in network order to convert
- * @return pointer to a global static (!) buffer that holds the ASCII
- * represenation of addr
- */
-char *
-ipaddr_ntoa(const ip_addr_t *addr)
-{
- static char str[16];
- return ipaddr_ntoa_r(addr, str, 16);
-}
-
-/**
- * Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used.
- *
- * @param addr ip address in network order to convert
- * @param buf target buffer where the string is stored
- * @param buflen length of buf
- * @return either pointer to buf which now holds the ASCII
- * representation of addr or NULL if buf was too small
- */
-char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen)
-{
- u32_t s_addr;
- char inv[3];
- char *rp;
- u8_t *ap;
- u8_t rem;
- u8_t n;
- u8_t i;
- int len = 0;
-
- s_addr = ip4_addr_get_u32(addr);
-
- rp = buf;
- ap = (u8_t *)&s_addr;
- for(n = 0; n < 4; n++) {
- i = 0;
- do {
- rem = *ap % (u8_t)10;
- *ap /= (u8_t)10;
- inv[i++] = '0' + rem;
- } while(*ap);
- while(i--) {
- if (len++ >= buflen) {
- return NULL;
- }
- *rp++ = inv[i];
- }
- if (len++ >= buflen) {
- return NULL;
- }
- *rp++ = '.';
- ap++;
- }
- *--rp = 0;
- return buf;
-}
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * This file is part of the lwIP TCP/IP stack.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_IP_H__
-#define __LWIP_IP_H__
-
-#include "lwip/opt.h"
-
-#include "lwip/def.h"
-#include "lwip/pbuf.h"
-#include "lwip/ip_addr.h"
-#include "lwip/err.h"
-#include "lwip/netif.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Currently, the function ip_output_if_opt() is only used with IGMP */
-#define IP_OPTIONS_SEND LWIP_IGMP
-
-#define IP_HLEN 20
-
-#define IP_PROTO_ICMP 1
-#define IP_PROTO_IGMP 2
-#define IP_PROTO_UDP 17
-#define IP_PROTO_UDPLITE 136
-#define IP_PROTO_TCP 6
-
-/* This is passed as the destination address to ip_output_if (not
- to ip_output), meaning that an IP header already is constructed
- in the pbuf. This is used when TCP retransmits. */
-#ifdef IP_HDRINCL
-#undef IP_HDRINCL
-#endif /* IP_HDRINCL */
-#define IP_HDRINCL NULL
-
-#if LWIP_NETIF_HWADDRHINT
-#define IP_PCB_ADDRHINT ;u8_t addr_hint
-#else
-#define IP_PCB_ADDRHINT
-#endif /* LWIP_NETIF_HWADDRHINT */
-
-/* This is the common part of all PCB types. It needs to be at the
- beginning of a PCB type definition. It is located here so that
- changes to this common part are made in one location instead of
- having to change all PCB structs. */
-#define IP_PCB \
- /* ip addresses in network byte order */ \
- ip_addr_t local_ip; \
- ip_addr_t remote_ip; \
- /* Socket options */ \
- u8_t so_options; \
- /* Type Of Service */ \
- u8_t tos; \
- /* Time To Live */ \
- u8_t ttl \
- /* link layer address resolution hint */ \
- IP_PCB_ADDRHINT
-
-struct ip_pcb {
-/* Common members of all PCB types */
- IP_PCB;
-};
-
-/*
- * Option flags per-socket. These are the same like SO_XXX.
- */
-/*#define SOF_DEBUG (u8_t)0x01U Unimplemented: turn on debugging info recording */
-#define SOF_ACCEPTCONN (u8_t)0x02U /* socket has had listen() */
-#define SOF_REUSEADDR (u8_t)0x04U /* allow local address reuse */
-#define SOF_KEEPALIVE (u8_t)0x08U /* keep connections alive */
-/*#define SOF_DONTROUTE (u8_t)0x10U Unimplemented: just use interface addresses */
-#define SOF_BROADCAST (u8_t)0x20U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
-/*#define SOF_USELOOPBACK (u8_t)0x40U Unimplemented: bypass hardware when possible */
-#define SOF_LINGER (u8_t)0x80U /* linger on close if data present */
-/*#define SOF_OOBINLINE (u16_t)0x0100U Unimplemented: leave received OOB data in line */
-/*#define SOF_REUSEPORT (u16_t)0x0200U Unimplemented: allow local address & port reuse */
-
-/* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */
-#define SOF_INHERITED (SOF_REUSEADDR|SOF_KEEPALIVE|SOF_LINGER/*|SOF_DEBUG|SOF_DONTROUTE|SOF_OOBINLINE*/)
-
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct ip_hdr {
- /* version / header length / type of service */
- PACK_STRUCT_FIELD(u16_t _v_hl_tos);
- /* total length */
- PACK_STRUCT_FIELD(u16_t _len);
- /* identification */
- PACK_STRUCT_FIELD(u16_t _id);
- /* fragment offset field */
- PACK_STRUCT_FIELD(u16_t _offset);
-#define IP_RF 0x8000 /* reserved fragment flag */
-#define IP_DF 0x4000 /* dont fragment flag */
-#define IP_MF 0x2000 /* more fragments flag */
-#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
- /* time to live */
- PACK_STRUCT_FIELD(u8_t _ttl);
- /* protocol*/
- PACK_STRUCT_FIELD(u8_t _proto);
- /* checksum */
- PACK_STRUCT_FIELD(u16_t _chksum);
- /* source and destination IP addresses */
- PACK_STRUCT_FIELD(ip_addr_t src);
- PACK_STRUCT_FIELD(ip_addr_t dest);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/epstruct.h"
-#endif
-
-#define IPH_V(hdr) (ntohs((hdr)->_v_hl_tos) >> 12)
-#define IPH_HL(hdr) ((ntohs((hdr)->_v_hl_tos) >> 8) & 0x0f)
-#define IPH_TOS(hdr) (ntohs((hdr)->_v_hl_tos) & 0xff)
-#define IPH_LEN(hdr) ((hdr)->_len)
-#define IPH_ID(hdr) ((hdr)->_id)
-#define IPH_OFFSET(hdr) ((hdr)->_offset)
-#define IPH_TTL(hdr) ((hdr)->_ttl)
-#define IPH_PROTO(hdr) ((hdr)->_proto)
-#define IPH_CHKSUM(hdr) ((hdr)->_chksum)
-
-#define IPH_VHLTOS_SET(hdr, v, hl, tos) (hdr)->_v_hl_tos = (htons(((v) << 12) | ((hl) << 8) | (tos)))
-#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len)
-#define IPH_ID_SET(hdr, id) (hdr)->_id = (id)
-#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off)
-#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl = (u8_t)(ttl)
-#define IPH_PROTO_SET(hdr, proto) (hdr)->_proto = (u8_t)(proto)
-#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum)
-
-/** The interface that provided the packet for the current callback invocation. */
-extern struct netif *current_netif;
-/** Header of the input packet currently being processed. */
-extern const struct ip_hdr *current_header;
-
-#define ip_init() /* Compatibility define, not init needed. */
-struct netif *ip_route(ip_addr_t *dest);
-err_t ip_input(struct pbuf *p, struct netif *inp);
-err_t ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
- u8_t ttl, u8_t tos, u8_t proto);
-err_t ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
- u8_t ttl, u8_t tos, u8_t proto,
- struct netif *netif);
-#if LWIP_NETIF_HWADDRHINT
-err_t ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
- u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint);
-#endif /* LWIP_NETIF_HWADDRHINT */
-#if IP_OPTIONS_SEND
-err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
- u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
- u16_t optlen);
-#endif /* IP_OPTIONS_SEND */
-/** Get the interface that received the current packet.
- * This function must only be called from a receive callback (udp_recv,
- * raw_recv, tcp_accept). It will return NULL otherwise. */
-#define ip_current_netif() (current_netif)
-/** Get the IP header of the current packet.
- * This function must only be called from a receive callback (udp_recv,
- * raw_recv, tcp_accept). It will return NULL otherwise. */
-#define ip_current_header() (current_header)
-#if IP_DEBUG
-void ip_debug_print(struct pbuf *p);
-#else
-#define ip_debug_print(p)
-#endif /* IP_DEBUG */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_IP_H__ */
-
-
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * This file is part of the lwIP TCP/IP stack.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_IP_ADDR_H__
-#define __LWIP_IP_ADDR_H__
-
-#include "lwip/opt.h"
-#include "lwip/def.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct _ip_addr {
- PACK_STRUCT_FIELD(u32_t addr);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/epstruct.h"
-#endif
-
-typedef struct _ip_addr ip_addr_t;
-
-/*
- * struct ipaddr2 is used in the definition of the ARP packet format in
- * order to support compilers that don't have structure packing.
- */
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct ip_addr2 {
- PACK_STRUCT_FIELD(u16_t addrw[2]);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/epstruct.h"
-#endif
-
-/* Forward declaration to not include netif.h */
-struct netif;
-
-extern const ip_addr_t ip_addr_any;
-extern const ip_addr_t ip_addr_broadcast;
-
-/** IP_ADDR_ can be used as a fixed IP address
- * for the wildcard and the broadcast address
- */
-#define IP_ADDR_ANY ((ip_addr_t *)&ip_addr_any)
-#define IP_ADDR_BROADCAST ((ip_addr_t *)&ip_addr_broadcast)
-
-/** 255.255.255.255 */
-#define IPADDR_NONE ((u32_t)0xffffffffUL)
-/** 127.0.0.1 */
-#define IPADDR_LOOPBACK ((u32_t)0x7f000001UL)
-/** 0.0.0.0 */
-#define IPADDR_ANY ((u32_t)0x00000000UL)
-/** 255.255.255.255 */
-#define IPADDR_BROADCAST ((u32_t)0xffffffffUL)
-
-/* Definitions of the bits in an Internet address integer.
-
- On subnets, host and network parts are found according to
- the subnet mask, not these masks. */
-#define IP_CLASSA(a) ((((u32_t)(a)) & 0x80000000UL) == 0)
-#define IP_CLASSA_NET 0xff000000
-#define IP_CLASSA_NSHIFT 24
-#define IP_CLASSA_HOST (0xffffffff & ~IP_CLASSA_NET)
-#define IP_CLASSA_MAX 128
-
-#define IP_CLASSB(a) ((((u32_t)(a)) & 0xc0000000UL) == 0x80000000UL)
-#define IP_CLASSB_NET 0xffff0000
-#define IP_CLASSB_NSHIFT 16
-#define IP_CLASSB_HOST (0xffffffff & ~IP_CLASSB_NET)
-#define IP_CLASSB_MAX 65536
-
-#define IP_CLASSC(a) ((((u32_t)(a)) & 0xe0000000UL) == 0xc0000000UL)
-#define IP_CLASSC_NET 0xffffff00
-#define IP_CLASSC_NSHIFT 8
-#define IP_CLASSC_HOST (0xffffffff & ~IP_CLASSC_NET)
-
-#define IP_CLASSD(a) (((u32_t)(a) & 0xf0000000UL) == 0xe0000000UL)
-#define IP_CLASSD_NET 0xf0000000 /* These ones aren't really */
-#define IP_CLASSD_NSHIFT 28 /* net and host fields, but */
-#define IP_CLASSD_HOST 0x0fffffff /* routing needn't know. */
-#define IP_MULTICAST(a) IP_CLASSD(a)
-
-#define IP_EXPERIMENTAL(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL)
-#define IP_BADCLASS(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL)
-
-#define IP_LOOPBACKNET 127 /* official! */
-
-
-#if BYTE_ORDER == BIG_ENDIAN
-/** Set an IP address given by the four byte-parts */
-#define IP4_ADDR(ipaddr, a,b,c,d) \
- (ipaddr)->addr = ((u32_t)((a) & 0xff) << 24) | \
- ((u32_t)((b) & 0xff) << 16) | \
- ((u32_t)((c) & 0xff) << 8) | \
- (u32_t)((d) & 0xff)
-#else
-/** Set an IP address given by the four byte-parts.
- Little-endian version that prevents the use of htonl. */
-#define IP4_ADDR(ipaddr, a,b,c,d) \
- (ipaddr)->addr = ((u32_t)((d) & 0xff) << 24) | \
- ((u32_t)((c) & 0xff) << 16) | \
- ((u32_t)((b) & 0xff) << 8) | \
- (u32_t)((a) & 0xff)
-#endif
-
-/** MEMCPY-like copying of IP addresses where addresses are known to be
- * 16-bit-aligned if the port is correctly configured (so a port could define
- * this to copying 2 u16_t's) - no NULL-pointer-checking needed. */
-#ifndef IPADDR2_COPY
-#define IPADDR2_COPY(dest, src) SMEMCPY(dest, src, sizeof(ip_addr_t))
-#endif
-
-/** Copy IP address - faster than ip_addr_set: no NULL check */
-#define ip_addr_copy(dest, src) ((dest).addr = (src).addr)
-/** Safely copy one IP address to another (src may be NULL) */
-#define ip_addr_set(dest, src) ((dest)->addr = \
- ((src) == NULL ? 0 : \
- (src)->addr))
-/** Set complete address to zero */
-#define ip_addr_set_zero(ipaddr) ((ipaddr)->addr = 0)
-/** Set address to IPADDR_ANY (no need for htonl()) */
-#define ip_addr_set_any(ipaddr) ((ipaddr)->addr = IPADDR_ANY)
-/** Set address to loopback address */
-#define ip_addr_set_loopback(ipaddr) ((ipaddr)->addr = PP_HTONL(IPADDR_LOOPBACK))
-/** Safely copy one IP address to another and change byte order
- * from host- to network-order. */
-#define ip_addr_set_hton(dest, src) ((dest)->addr = \
- ((src) == NULL ? 0:\
- htonl((src)->addr)))
-/** IPv4 only: set the IP address given as an u32_t */
-#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32))
-/** IPv4 only: get the IP address as an u32_t */
-#define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr)
-
-/** Get the network address by combining host address with netmask */
-#define ip_addr_get_network(target, host, netmask) ((target)->addr = ((host)->addr) & ((netmask)->addr))
-
-/**
- * Determine if two address are on the same network.
- *
- * @arg addr1 IP address 1
- * @arg addr2 IP address 2
- * @arg mask network identifier mask
- * @return !0 if the network identifiers of both address match
- */
-#define ip_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \
- (mask)->addr) == \
- ((addr2)->addr & \
- (mask)->addr))
-#define ip_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr)
-
-#define ip_addr_isany(addr1) ((addr1) == NULL || (addr1)->addr == IPADDR_ANY)
-
-u8_t ip_addr_isbroadcast(const ip_addr_t *, const struct netif *);
-
-#define ip_addr_ismulticast(addr1) (((addr1)->addr & PP_HTONL(0xf0000000UL)) == PP_HTONL(0xe0000000UL))
-
-#define ip_addr_islinklocal(addr1) (((addr1)->addr & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xa9fe0000UL))
-
-#define ip_addr_debug_print(debug, ipaddr) \
- LWIP_DEBUGF(debug, ("%"U16_F".%"U16_F".%"U16_F".%"U16_F, \
- ipaddr != NULL ? ip4_addr1_16(ipaddr) : 0, \
- ipaddr != NULL ? ip4_addr2_16(ipaddr) : 0, \
- ipaddr != NULL ? ip4_addr3_16(ipaddr) : 0, \
- ipaddr != NULL ? ip4_addr4_16(ipaddr) : 0))
-
-/* Get one byte from the 4-byte address */
-#define ip4_addr1(ipaddr) (((u8_t*)(ipaddr))[0])
-#define ip4_addr2(ipaddr) (((u8_t*)(ipaddr))[1])
-#define ip4_addr3(ipaddr) (((u8_t*)(ipaddr))[2])
-#define ip4_addr4(ipaddr) (((u8_t*)(ipaddr))[3])
-/* These are cast to u16_t, with the intent that they are often arguments
- * to printf using the U16_F format from cc.h. */
-#define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr))
-#define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr))
-#define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr))
-#define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr))
-
-/** For backwards compatibility */
-#define ip_ntoa(ipaddr) ipaddr_ntoa(ipaddr)
-
-u32_t ipaddr_addr(const char *cp);
-int ipaddr_aton(const char *cp, ip_addr_t *addr);
-/** returns ptr to static buffer; not reentrant! */
-char *ipaddr_ntoa(const ip_addr_t *addr);
-char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_IP_ADDR_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * This file is part of the lwIP TCP/IP stack.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_ICMP_H__
-#define __LWIP_ICMP_H__
-
-#include "lwip/opt.h"
-
-#if LWIP_ICMP /* don't build if not configured for use in lwipopts.h */
-
-#include "lwip/pbuf.h"
-#include "lwip/netif.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ICMP6_DUR 1
-#define ICMP6_TE 3
-#define ICMP6_ECHO 128 /* echo */
-#define ICMP6_ER 129 /* echo reply */
-
-
-enum icmp_dur_type {
- ICMP_DUR_NET = 0, /* net unreachable */
- ICMP_DUR_HOST = 1, /* host unreachable */
- ICMP_DUR_PROTO = 2, /* protocol unreachable */
- ICMP_DUR_PORT = 3, /* port unreachable */
- ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */
- ICMP_DUR_SR = 5 /* source route failed */
-};
-
-enum icmp_te_type {
- ICMP_TE_TTL = 0, /* time to live exceeded in transit */
- ICMP_TE_FRAG = 1 /* fragment reassembly time exceeded */
-};
-
-void icmp_input(struct pbuf *p, struct netif *inp);
-
-void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t);
-void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t);
-
-struct icmp_echo_hdr {
- u8_t type;
- u8_t icode;
- u16_t chksum;
- u16_t id;
- u16_t seqno;
-};
-
-struct icmp_dur_hdr {
- u8_t type;
- u8_t icode;
- u16_t chksum;
- u32_t unused;
-};
-
-struct icmp_te_hdr {
- u8_t type;
- u8_t icode;
- u16_t chksum;
- u32_t unused;
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* LWIP_ICMP */
-
-#endif /* __LWIP_ICMP_H__ */
-
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * This file is part of the lwIP TCP/IP stack.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_INET_H__
-#define __LWIP_INET_H__
-
-#include "lwip/opt.h"
-#include "lwip/pbuf.h"
-#include "lwip/ip_addr.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-u16_t inet_chksum(void *data, u16_t len);
-u16_t inet_chksum_pbuf(struct pbuf *p);
-u16_t inet_chksum_pseudo(struct pbuf *p,
- struct ip_addr *src, struct ip_addr *dest,
- u8_t proto, u32_t proto_len);
-
-u32_t inet_addr(const char *cp);
-s8_t inet_aton(const char *cp, struct in_addr *addr);
-
-#ifndef _MACHINE_ENDIAN_H_
-#ifndef _NETINET_IN_H
-#ifndef _LINUX_BYTEORDER_GENERIC_H
-u16_t htons(u16_t n);
-u16_t ntohs(u16_t n);
-u32_t htonl(u32_t n);
-u32_t ntohl(u32_t n);
-#endif /* _LINUX_BYTEORDER_GENERIC_H */
-#endif /* _NETINET_IN_H */
-#endif /* _MACHINE_ENDIAN_H_ */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_INET_H__ */
-
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * This file is part of the lwIP TCP/IP stack.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_IP_H__
-#define __LWIP_IP_H__
-
-#include "lwip/opt.h"
-#include "lwip/def.h"
-#include "lwip/pbuf.h"
-#include "lwip/ip_addr.h"
-
-#include "lwip/err.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define IP_HLEN 40
-
-#define IP_PROTO_ICMP 58
-#define IP_PROTO_UDP 17
-#define IP_PROTO_UDPLITE 136
-#define IP_PROTO_TCP 6
-
-/* This is passed as the destination address to ip_output_if (not
- to ip_output), meaning that an IP header already is constructed
- in the pbuf. This is used when TCP retransmits. */
-#ifdef IP_HDRINCL
-#undef IP_HDRINCL
-#endif /* IP_HDRINCL */
-#define IP_HDRINCL NULL
-
-#if LWIP_NETIF_HWADDRHINT
-#define IP_PCB_ADDRHINT ;u8_t addr_hint
-#else
-#define IP_PCB_ADDRHINT
-#endif /* LWIP_NETIF_HWADDRHINT */
-
-/* This is the common part of all PCB types. It needs to be at the
- beginning of a PCB type definition. It is located here so that
- changes to this common part are made in one location instead of
- having to change all PCB structs. */
-#define IP_PCB struct ip_addr local_ip; \
- struct ip_addr remote_ip; \
- /* Socket options */ \
- u16_t so_options; \
- /* Type Of Service */ \
- u8_t tos; \
- /* Time To Live */ \
- u8_t ttl; \
- /* link layer address resolution hint */ \
- IP_PCB_ADDRHINT
-
-
-/* The IPv6 header. */
-struct ip_hdr {
-#if BYTE_ORDER == LITTLE_ENDIAN
- u8_t tclass1:4, v:4;
- u8_t flow1:4, tclass2:4;
-#else
- u8_t v:4, tclass1:4;
- u8_t tclass2:8, flow1:4;
-#endif
- u16_t flow2;
- u16_t len; /* payload length */
- u8_t nexthdr; /* next header */
- u8_t hoplim; /* hop limit (TTL) */
- struct ip_addr src, dest; /* source and destination IP addresses */
-};
-
-#define IPH_PROTO(hdr) (iphdr->nexthdr)
-
-void ip_init(void);
-
-#include "lwip/netif.h"
-
-struct netif *ip_route(struct ip_addr *dest);
-
-void ip_input(struct pbuf *p, struct netif *inp);
-
-/* source and destination addresses in network byte order, please */
-err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
- u8_t ttl, u8_t proto);
-
-err_t ip_output_if(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
- u8_t ttl, u8_t proto,
- struct netif *netif);
-
-#define ip_current_netif() NULL
-#define ip_current_header() NULL
-
-#if IP_DEBUG
-void ip_debug_print(struct pbuf *p);
-#endif /* IP_DEBUG */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_IP_H__ */
-
-
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * This file is part of the lwIP TCP/IP stack.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __LWIP_IP_ADDR_H__
-#define __LWIP_IP_ADDR_H__
-
-#include "lwip/opt.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define IP_ADDR_ANY 0
-
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
- struct ip_addr {
- PACK_STRUCT_FIELD(u32_t addr[4]);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/epstruct.h"
-#endif
-
-/*
- * struct ipaddr2 is used in the definition of the ARP packet format in
- * order to support compilers that don't have structure packing.
- */
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/bpstruct.h"
-#endif
-PACK_STRUCT_BEGIN
-struct ip_addr2 {
- PACK_STRUCT_FIELD(u16_t addrw[2]);
-} PACK_STRUCT_STRUCT;
-PACK_STRUCT_END
-#ifdef PACK_STRUCT_USE_INCLUDES
-# include "arch/epstruct.h"
-#endif
-
-#define IP6_ADDR(ipaddr, a,b,c,d,e,f,g,h) do { (ipaddr)->addr[0] = htonl((u32_t)((a & 0xffff) << 16) | (b & 0xffff)); \
- (ipaddr)->addr[1] = htonl(((c & 0xffff) << 16) | (d & 0xffff)); \
- (ipaddr)->addr[2] = htonl(((e & 0xffff) << 16) | (f & 0xffff)); \
- (ipaddr)->addr[3] = htonl(((g & 0xffff) << 16) | (h & 0xffff)); } while(0)
-
-u8_t ip_addr_netcmp(struct ip_addr *addr1, struct ip_addr *addr2,
- struct ip_addr *mask);
-u8_t ip_addr_cmp(struct ip_addr *addr1, struct ip_addr *addr2);
-void ip_addr_set(struct ip_addr *dest, struct ip_addr *src);
-u8_t ip_addr_isany(struct ip_addr *addr);
-
-#define ip_addr_debug_print(debug, ipaddr) \
- LWIP_DEBUGF(debug, ("%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F":%"X32_F"\n", \
- (ntohl(ipaddr->addr[0]) >> 16) & 0xffff, \
- ntohl(ipaddr->addr[0]) & 0xffff, \
- (ntohl(ipaddr->addr[1]) >> 16) & 0xffff, \
- ntohl(ipaddr->addr[1]) & 0xffff, \
- (ntohl(ipaddr->addr[2]) >> 16) & 0xffff, \
- ntohl(ipaddr->addr[2]) & 0xffff, \
- (ntohl(ipaddr->addr[3]) >> 16) & 0xffff, \
- ntohl(ipaddr->addr[3]) & 0xffff));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LWIP_IP_ADDR_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- *
- * This file is part of the lwIP TCP/IP stack.
- *
- * Author: Adam Dunkels <adam@sics.se>
- *
- */
-#ifndef __NETIF_LOOPIF_H__
-#define __NETIF_LOOPIF_H__
-
-#include "lwip/opt.h"
-#include "lwip/netif.h"
-#include "lwip/err.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if !LWIP_NETIF_LOOPBACK_MULTITHREADING
-#define loopif_poll netif_poll
-#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */
-
-err_t loopif_init(struct netif *netif);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __NETIF_LOOPIF_H__ */
+++ /dev/null
-/*!
- * \file support_imx.cc
- * \brief Support for the i.MX platform
- *
- * \date 2008-02-04
- * \author Adam Lackorznynski <adam@os.inf.tu-dresden.de>
- *
- */
-/*
- * (c) 2008-2009 Author(s)
- * economic rights: Technische Universität Dresden (Germany)
- *
- * This file is part of TUD:OS and distributed under the terms of the
- * GNU General Public License 2.
- * Please see the COPYING-GPL-2 file for details.
- */
-
-#include "support.h"
-#include <l4/drivers/uart_imx.h>
-
-namespace {
-class Platform_arm_imx : public Platform_single_region_ram
-{
- bool probe() { return true; }
-
- void init()
- {
-#ifdef PLATFORM_TYPE_imx21
- static L4::Uart_imx21 _uart(0, 0);
- _uart.startup(0x1000A000);
-#elif defined(PLATFORM_TYPE_imx35)
- static L4::Uart_imx35 _uart(0, 0);
- _uart.startup(0x43f90000); // UART-1
- //_uart.startup(0x43f94000); // UART-2
- //_uart.startup(0x5000c000); // UART-3
-#elif defined(PLATFORM_TYPE_imx51)
- static L4::Uart_imx51 _uart(0, 0);
- _uart.startup(0x73fbc000);
-#else
-#error Which platform type?
-#endif
- set_stdio_uart(&_uart);
- }
-};
-}
-
-REGISTER_PLATFORM(Platform_arm_imx);
+++ /dev/null
-/*!
- * \file support_integrator.cc
- * \brief Support for the integrator platform
- *
- * \date 2008-01-02
- * \author Adam Lackorznynski <adam@os.inf.tu-dresden.de>
- *
- */
-/*
- * (c) 2008-2009 Author(s)
- * economic rights: Technische Universität Dresden (Germany)
- *
- * This file is part of TUD:OS and distributed under the terms of the
- * GNU General Public License 2.
- * Please see the COPYING-GPL-2 file for details.
- */
-
-#include "support.h"
-#include <l4/drivers/uart_pl011.h>
-
-namespace {
-class Platform_arm_int : public Platform_single_region_ram
-{
- bool probe() { return true; }
-
- void init()
- {
- static L4::Uart_pl011 _uart(1, 1);
- _uart.startup(0x16000000);
- set_stdio_uart(&_uart);
- }
-};
-}
-
-REGISTER_PLATFORM(Platform_arm_int);
+++ /dev/null
-/*!
- * \file support_kirkwood.cc
- * \brief Support for the kirkwood platform
- *
- * \date 2010-11
- * \author Adam Lackorznynski <adam@os.inf.tu-dresden.de>
- *
- */
-/*
- * (c) 2010 Author(s)
- * economic rights: Technische Universität Dresden (Germany)
- *
- * This file is part of TUD:OS and distributed under the terms of the
- * GNU General Public License 2.
- * Please see the COPYING-GPL-2 file for details.
- */
-
-#include "support.h"
-#include <l4/drivers/uart_pxa.h>
-
-namespace {
-class Platform_arm_kirkwood : public Platform_single_region_ram
-{
- bool probe() { return true; }
-
- void init()
- {
- static L4::Uart_pxa _uart(1, 1);
- _uart.startup(0xf1012000); // uart0
- //_uart.startup(0xf1012100); // uart1
- _uart.change_mode(0x3, 8500); // TCLK=200000000, Divisor: 108=TCLK/115200/16
- set_stdio_uart(&_uart);
-
-
- // SPI init, as there's an interrupt pending when coming from u-boot on
- // the dockstar, so make it go away
- *(unsigned *)0xf1010600 = 0; // disable
- *(unsigned *)0xf1010614 = 0; // mask interrupt
- *(unsigned *)0xf1010610 = 1; // clear interrupt
- }
-};
-}
-
-REGISTER_PLATFORM(Platform_arm_kirkwood);
+++ /dev/null
-/**
- * \file
- * \brief Support for the MPC52000
- *
- * \date 2009-02-16
- * \author Sebastian Sumpf <sumpf@os.inf.tu-dresden.de>
- *
- */
-/*
- * (c) 2009 Author(s)
- * economic rights: Technische Universität Dresden (Germany)
- *
- * This file is part of TUD:OS and distributed under the terms of the
- * GNU General Public License 2.
- * Please see the COPYING-GPL-2 file for details.
- */
-
-#include "support.h"
-#include <l4/drivers/uart_of.h>
-
-
-namespace {
-class Platform_ppc_mpc52000 : public Platform_base
-{
- bool probe() { return true; }
-
- void init()
- {
- static L4::Uart_of _uart;
- _uart.startup(0);
- set_stdio_uart(&_uart);
- }
- void setup_memory_map(l4util_mb_info_t *,
- Region_list *, Region_list *)
- {
- // still done in startup.cc
- }
-};
-}
-
-REGISTER_PLATFORM(Platform_ppc_mpc52000);
+++ /dev/null
-/**
- * \file support_om.cc
- * \brief Support for the OpenMoko platform
- *
- * \date 2008
- * \author Adam Lackorznynski <adam@os.inf.tu-dresden.de>
- *
- */
-/*
- * (c) 2008-2009 Author(s)
- * economic rights: Technische Universität Dresden (Germany)
- *
- * This file is part of TUD:OS and distributed under the terms of the
- * GNU General Public License 2.
- * Please see the COPYING-GPL-2 file for details.
- */
-
-
-#include "support.h"
-
-#include <l4/drivers/uart_s3c2410.h>
-#include <l4/drivers/uart_dummy.h>
-
-#define UART_TYPE Uart_s3c2410
-//#define UART_TYPE Uart_dummy
-
-namespace {
-class Platform_arm_om : public Platform_single_region_ram
-{
- bool probe() { return true; }
-
- void init()
- {
- static L4::UART_TYPE _uart(1,1);
- _uart.startup(0x50000000);
- set_stdio_uart(&_uart);
- }
-};
-}
-
-REGISTER_PLATFORM(Platform_arm_om);
+++ /dev/null
-/*!
- * \file support_beagleboard.cc
- * \brief Support for the Beagleboard
- *
- * \date 2009-08
- * \author Adam Lackorznynski <adam@os.inf.tu-dresden.de>
- *
- */
-/*
- * (c) 2009 Author(s)
- * economic rights: Technische Universität Dresden (Germany)
- *
- * This file is part of TUD:OS and distributed under the terms of the
- * GNU General Public License 2.
- * Please see the COPYING-GPL-2 file for details.
- */
-
-#include "support.h"
-#include <l4/drivers/uart_omap35x.h>
-
-namespace {
-class Platform_arm_omap : public Platform_single_region_ram
-{
- bool probe() { return true; }
-
- void init()
- {
- static L4::Uart_omap35x _uart(1, 1);
-#ifdef PLATFORM_TYPE_beagleboard
- _uart.startup(0x49020000);
-#elif defined(PLATFORM_TYPE_omap3evm)
- _uart.startup(0x4806a000);
-#elif defined(PLATFORM_TYPE_pandaboard)
- _uart.startup(0x48020000);
-#else
-#error Unknown platform
-#endif
- set_stdio_uart(&_uart);
- }
-};
-}
-
-REGISTER_PLATFORM(Platform_arm_omap);
+++ /dev/null
-/*!
- * \file support_pxa.cc
- * \brief Support for the PXA platform
- *
- * \date 2008-01-04
- * \author Adam Lackorznynski <adam@os.inf.tu-dresden.de>
- *
- */
-/*
- * (c) 2008-2009 Author(s)
- * economic rights: Technische Universität Dresden (Germany)
- *
- * This file is part of TUD:OS and distributed under the terms of the
- * GNU General Public License 2.
- * Please see the COPYING-GPL-2 file for details.
- */
-
-#include "support.h"
-#include <l4/drivers/uart_pxa.h>
-
-namespace {
-class Platform_arm_pxa : public Platform_single_region_ram
-{
- bool probe() { return true; }
-
- void init()
- {
- static L4::Uart_pxa _uart(1,1);
- _uart.startup(0x40100000);
- set_stdio_uart(&_uart);
- }
-};
-}
-
-REGISTER_PLATFORM(Platform_arm_pxa);
+++ /dev/null
-/*!
- * \file support_rv.cc
- * \brief Support for the rv platform
- *
- * \date 2008-01-02
- * \author Adam Lackorznynski <adam@os.inf.tu-dresden.de>
- *
- */
-/*
- * (c) 2008-2009 Author(s)
- * economic rights: Technische Universität Dresden (Germany)
- *
- * This file is part of TUD:OS and distributed under the terms of the
- * GNU General Public License 2.
- * Please see the COPYING-GPL-2 file for details.
- */
-
-#include "support.h"
-
-#include <l4/drivers/uart_pl011.h>
-
-namespace {
-class Platform_arm_rv : public Platform_single_region_ram
-{
- bool probe() { return true; }
- void init()
- {
- static L4::Uart_pl011 _uart(36,36);
- _uart.startup(0x10009000);
- set_stdio_uart(&_uart);
- }
-};
-}
-
-REGISTER_PLATFORM(Platform_arm_rv);
+++ /dev/null
-/*!
- * \file support_sa1000.cc
- * \brief Support for SA1000 platform
- *
- * \date 2008-01-02
- * \author Adam Lackorznynski <adam@os.inf.tu-dresden.de>
- *
- */
-/*
- * (c) 2008-2009 Author(s)
- * economic rights: Technische Universität Dresden (Germany)
- *
- * This file is part of TUD:OS and distributed under the terms of the
- * GNU General Public License 2.
- * Please see the COPYING-GPL-2 file for details.
- */
-
-#include "support.h"
-#include <l4/drivers/uart_sa1000.h>
-
-namespace {
-class Platform_arm_sa1000 : public Platform_single_region_ram
-{
- bool probe() { return true; }
-
- void init()
- {
- static L4::Uart_sa1000 _uart(1,1);
- _uart.startup(0x80010000);
- //_uart.startup(0x80050000);
- set_stdio_uart(&_uart);
- }
-};
-}
-
-REGISTER_PLATFORM(Platform_arm_sa1000);
+++ /dev/null
-/**
- * \file support_sparc_leon3.cc
- * \brief Support for the Sparc LEON3 platform
- *
- * \date 2010
- * \author Björn Döbel <doebel@os.inf.tu-dresden.de>
- *
- */
-/*
- * (c) 2010 Author(s)
- * economic rights: Technische Universität Dresden (Germany)
- *
- * This file is part of TUD:OS and distributed under the terms of the
- * GNU General Public License 2.
- * Please see the COPYING-GPL-2 file for details.
- */
-
-#include "support.h"
-
-#include <l4/drivers/uart_dummy.h>
-
-#define UART_TYPE Uart_dummy
-
-namespace {
-class Platform_leon3 //: public Platform_single_region_ram
-{
- bool probe() { return true; }
-
- void init()
- {
- asm volatile("ta 0\n");
-#if 0
- static L4::UART_TYPE _uart(1,1);
- _uart.startup(0x50000000);
- set_stdio_uart(&_uart);
-#endif
- }
-};
-}
-
-REGISTER_PLATFORM(Platform_leon3);
+++ /dev/null
-/*!
- * \file
- * \brief Support for Tegra 2 platforms
- *
- * \date 2010-05
- * \author Adam Lackorznynski <adam@os.inf.tu-dresden.de>
- *
- */
-/*
- * (c) 2010 Author(s)
- * economic rights: Technische Universität Dresden (Germany)
- *
- * This file is part of TUD:OS and distributed under the terms of the
- * GNU General Public License 2.
- * Please see the COPYING-GPL-2 file for details.
- */
-
-/* Init-code from http://android.git.kernel.org/?p=kernel/tegra.git */
-
-#include "support.h"
-#include <l4/drivers/uart_pxa.h>
-
-namespace {
-class Platform_arm_tegra2 : public Platform_base
-{
-private:
- void some_delay(int d) const
- {
- for (int i = 0; i < d; i++)
- asm volatile("":::"memory");
- }
-
-public:
- bool probe() { return true; }
-
- void init()
- {
- volatile unsigned long *addr;
-
- addr = (volatile unsigned long *)0x600060a0;
- *addr = 0x5011b00c;
-
- /* PLLP_OUTA_0 */
- addr = (volatile unsigned long *)0x600060a4;
- *addr = 0x10031c03;
-
- /* PLLP_OUTB_0 */
- addr = (volatile unsigned long *)0x600060a8;
- *addr = 0x06030a03;
-
- /* PLLP_MISC_0 */
- addr = (volatile unsigned long *)0x600060ac;
- *addr = 0x00000800;
-
- some_delay(1000000);
-
- /* UARTD clock source is PLLP_OUT0 */
- addr = (volatile unsigned long *)0x600061c0;
- *addr = 0;
-
- /* Enable clock to UARTD */
- addr = (volatile unsigned long *)0x60006018;
- *addr |= 2;
- some_delay(5000);
-
- /* Deassert reset to UARTD */
- addr = (volatile unsigned long *)0x6000600c;
- *addr &= ~2;
-
- some_delay(5000);
-
- static L4::Uart_pxa _uart(1, 1);
- _uart.startup(0x70006300);
- _uart.change_mode(3, 7876);
- set_stdio_uart(&_uart);
- }
-
- void setup_memory_map(l4util_mb_info_t *,
- Region_list *ram, Region_list *)
- {
- ram->add(Region::n(0x0, 448 << 20, ".ram", Region::Ram));
- ram->add(Region::n(512 << 20, 1024 << 20, ".ram", Region::Ram));
- }
-};
-}
-
-REGISTER_PLATFORM(Platform_arm_tegra2);
+++ /dev/null
-/*!
- * \file support_x86.cc
- * \brief Support for the x86 platform
- *
- * \date 2008-01-02
- * \author Adam Lackorznynski <adam@os.inf.tu-dresden.de>
- *
- */
-/*
- * (c) 2008-2009 Author(s)
- * economic rights: Technische Universität Dresden (Germany)
- *
- * This file is part of TUD:OS and distributed under the terms of the
- * GNU General Public License 2.
- * Please see the COPYING-GPL-2 file for details.
- */
-
-#include "support.h"
-
-namespace L4
-{
- class Uart_x86 : public Uart
- {
- private:
- unsigned long _base;
-
- inline unsigned long rd(unsigned long reg) const;
- inline void wr(unsigned long reg, unsigned long val) const;
-
- public:
- Uart_x86(int rx_irq, int tx_irq)
- : Uart(rx_irq, tx_irq), _base(~0UL) {}
- bool startup(unsigned long base);
- void shutdown();
- bool enable_rx_irq(bool enable = true);
- bool enable_tx_irq(bool enable = true);
- bool change_mode(Transfer_mode m, Baud_rate r);
- int get_char(bool blocking = true) const;
- int char_avail() const;
- inline void out_char(char c) const;
- int write(char const *s, unsigned long count) const;
- };
-};
-
-
-#include <string.h>
-#include "base_critical.h"
-#include "ARCH-x86/serial.h"
-#include <l4/util/cpu.h>
-#include <l4/util/port_io.h>
-#include <assert.h>
-
-/** VGA console output */
-
-static void
-vga_init()
-{
- /* Reset any scrolling */
- l4util_out32(0xc, 0x3d4);
- l4util_out32(0, 0x3d5);
- l4util_out32(0xd, 0x3d4);
- l4util_out32(0, 0x3d5);
-}
-
-static void
-vga_putchar(unsigned char c)
-{
- static int ofs = -1, esc, esc_val, attr = 0x07;
- unsigned char *vidbase = (unsigned char*)0xb8000;
-
- base_critical_enter();
-
- if (ofs < 0)
- {
- /* Called for the first time - initialize. */
- ofs = 80*2*24;
- vga_putchar('\n');
- }
-
- switch (esc)
- {
- case 1:
- if (c == '[')
- {
- esc++;
- goto done;
- }
- esc = 0;
- break;
-
- case 2:
- if (c >= '0' && c <= '9')
- {
- esc_val = 10*esc_val + c - '0';
- goto done;
- }
- if (c == 'm')
- {
- attr = esc_val ? 0x0f : 0x07;
- goto done;
- }
- esc = 0;
- break;
- }
-
- switch (c)
- {
- case '\n':
- memmove(vidbase, vidbase+80*2, 80*2*24);
- memset(vidbase+80*2*24, 0, 80*2);
- /* fall through... */
- case '\r':
- ofs = 0;
- break;
-
- case '\t':
- ofs = (ofs + 8) & ~7;
- break;
-
- case '\033':
- esc = 1;
- esc_val = 0;
- break;
-
- default:
- /* Wrap if we reach the end of a line. */
- if (ofs >= 80)
- vga_putchar('\n');
-
- /* Stuff the character into the video buffer. */
- {
- volatile unsigned char *p = vidbase + 80*2*24 + ofs*2;
- p[0] = c;
- p[1] = attr;
- ofs++;
- }
- break;
- }
-
-done:
- base_critical_leave();
-}
-
-/** Poor man's getchar, only returns raw scan code. We don't need to know
- * _which_ key was pressed, we only want to know _if_ a key was pressed. */
-static int
-raw_keyboard_getscancode(void)
-{
- unsigned status, scan_code;
-
- base_critical_enter();
-
- l4util_cpu_pause();
-
- /* Wait until a scan code is ready and read it. */
- status = l4util_in8(0x64);
- if ((status & 0x01) == 0)
- {
- base_critical_leave();
- return -1;
- }
- scan_code = l4util_in8(0x60);
-
- /* Drop mouse events */
- if ((status & 0x20) != 0)
- {
- base_critical_leave();
- return -1;
- }
-
- base_critical_leave();
- return scan_code;
-}
-
-namespace L4
-{
- bool Uart_x86::startup(unsigned long /*base*/)
- // real uart init will be made by startup.cc if told by cmdline
- { vga_init(); return true; }
-
- void Uart_x86::shutdown() {}
- bool Uart_x86::enable_rx_irq(bool) { return true; }
- bool Uart_x86::enable_tx_irq(bool) { return false; }
- bool Uart_x86::change_mode(Transfer_mode, Baud_rate) { return false; }
-
- int Uart_x86::get_char(bool blocking) const
- {
- int c;
- do {
- c = com_cons_try_getchar();
- if (c == -1)
- c = raw_keyboard_getscancode();
- l4util_cpu_pause();
- } while (c == -1 && blocking);
-
- return c;
- }
-
- int Uart_x86::char_avail() const
- {
- return com_cons_char_avail();
- }
-
- void Uart_x86::out_char(char c) const
- {
- vga_putchar(c); // vga out
- com_cons_putchar(c); // serial out
- }
-
- int Uart_x86::write(char const *s, unsigned long count) const
- {
- unsigned long c = count;
- while (c)
- {
- if (*s == 10)
- out_char(13);
- out_char(*s++);
- --c;
- }
- return count;
- }
-};
-
-
-static inline l4_uint32_t
-pci_conf_addr(l4_uint32_t bus, l4_uint32_t dev, l4_uint32_t fn, l4_uint32_t reg)
-{ return 0x80000000 | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3); }
-
-static l4_uint32_t pci_read(unsigned char bus, l4_uint32_t dev,
- l4_uint32_t fn, l4_uint32_t reg,
- unsigned char width)
-{
- l4util_out32(pci_conf_addr(bus, dev, fn, reg), 0xcf8);
-
- switch (width)
- {
- case 8: return l4util_in8(0xcfc + (reg & 3));
- case 16: return l4util_in16((0xcfc + (reg & 3)) & ~1UL);
- case 32: return l4util_in32(0xcfc);
- }
- return 0;
-}
-
-static void pci_write(unsigned char bus, l4_uint32_t dev,
- l4_uint32_t fn, l4_uint32_t reg,
- l4_uint32_t val, unsigned char width)
-{
- l4util_out32(pci_conf_addr(bus, dev, fn, reg), 0xcf8);
-
- switch (width)
- {
- case 8: l4util_out8(val, 0xcfc + (reg & 3)); break;
- case 16: l4util_out16(val, (0xcfc + (reg & 3)) & ~1UL); break;
- case 32: l4util_out32(val, 0xcfc); break;
- }
-}
-
-static void pci_enable_io(unsigned char bus, l4_uint32_t dev,
- l4_uint32_t fn)
-{
- unsigned cmd = pci_read(bus, dev, fn, 4, 16);
- pci_write(bus, dev, fn, 4, cmd | 1, 16);
-}
-
-#include <stdio.h>
-
-namespace {
-
-struct Resource
-{
- enum Type { NO_BAR, IO_BAR, MEM_BAR };
- Type type;
- unsigned long base;
- unsigned long len;
- Resource() : type(NO_BAR) {}
-};
-
-enum { NUM_BARS = 6 };
-
-struct Serial_board
-{
- int num_ports;
- int first_bar;
- bool port_per_bar;
- Resource bars[NUM_BARS];
-
- unsigned long get_port(int idx)
- {
- if (idx >= num_ports)
- return 0;
-
- if (port_per_bar)
- return bars[first_bar + idx].base;
-
- return bars[first_bar].base + 8 * idx;
- }
-};
-
-
-}
-
-static
-int pci_handle_serial_dev(unsigned char bus, l4_uint32_t dev,
- l4_uint32_t subdev, bool scan_only,
- Serial_board *board)
-{
-#if 0
- bool dev_enabled = false;
-#endif
-
-
- // read bars
- int num_iobars = 0;
- int num_membars = 0;
- int first_port = -1;
- for (int bar = 0; bar < NUM_BARS; ++bar)
- {
- int a = 0x10 + bar * 4;
-
- unsigned v = pci_read(bus, dev, subdev, a, 32);
- pci_write(bus, dev, subdev, a, ~0U, 32);
- unsigned x = pci_read(bus, dev, subdev, a, 32);
- pci_write(bus, dev, subdev, a, v, 32);
-
- if (!v)
- continue;
-
- int s;
- for (s = 2; s < 32; ++s)
- if ((x >> s) & 1)
- break;
-
- board->bars[bar].base = v & ~3UL;
- board->bars[bar].len = 1 << s;
- board->bars[bar].type = (v & 1) ? Resource::IO_BAR : Resource::MEM_BAR;
-
- if (scan_only)
- printf("BAR%d: %04x (sz=%d)\n", bar, v & ~3, 1 << s);
-
- switch (board->bars[bar].type)
- {
- case Resource::IO_BAR:
- ++num_iobars;
- if (first_port == -1)
- first_port = bar;
- break;
- case Resource::MEM_BAR:
- ++num_membars;
- break;
- default:
- break;
- }
- }
-
- if (num_membars <= 1 && num_iobars == 1)
- {
- board->first_bar = first_port;
- board->num_ports = board->bars[first_port].len / 8;
- board->port_per_bar = false;
- pci_enable_io(bus, dev, subdev);
- return 1;
- }
-
-
- board->num_ports = 0;
- board->first_bar = -1;
-
- for (int bar = 0; bar < NUM_BARS; ++bar)
- {
- if (board->bars[bar].type == Resource::IO_BAR && board->bars[bar].len == 8
- && (board->first_bar == -1
- || (board->first_bar + board->num_ports) == bar))
- {
- ++board->num_ports;
- if (board->first_bar == -1)
- board->first_bar = bar;
- }
- }
-
- board->port_per_bar = true;
- return board->num_ports;
-
-#if 0
-
- // for now we only take IO-BARs of size 8
- if (v & 1)
- {
-
- if (!scan_only && !dev_enabled)
- {
- pci_enable_io(bus, dev, subdev);
- dev_enabled = true;
- }
-
- if (scan_only)
- printf("BAR%d: %04x (sz=%d)\n", bar, v & ~3, 1 << s);
-
- if (s == 3)
- {
- if (scan_only)
- printf(" Potential serial port\n");
- else
- return v & ~3;
- }
- }
- else
- if (scan_only)
- printf("BAR%d: %08x (sz=%d)\n", bar, v & ~0xf, 1 << s);
- }
- return 0;
-#endif
-}
-
-static unsigned long _search_pci_serial_devs(Serial_board *board, bool scan_only)
-{
- l4_umword_t bus, buses, dev;
-
- for (bus=0, buses=20; bus<buses; bus++)
- {
- for (dev = 0; dev < 32; dev++)
- {
- unsigned char hdr_type = pci_read(bus, dev, 0, 0xe, 8);
- l4_umword_t subdevs = (hdr_type & 0x80) ? 8 : 1;
-
- for (l4_umword_t subdev = 0; subdev < subdevs; subdev++)
- {
- unsigned vendor = pci_read(bus, dev, subdev, 0, 16);
- unsigned device = pci_read(bus, dev, subdev, 2, 16);
-
- if ((vendor == 0xffff && device == 0xffff) ||
- (device == 0x0000 && device == 0x0000))
- break;
-
- unsigned classcode = pci_read(bus, dev, subdev, 0x0b, 8);
- unsigned subclass = pci_read(bus, dev, subdev, 0x0a, 8);
-
- if (classcode == 0x06 && subclass == 0x04)
- buses++;
-
- unsigned prog = pci_read(bus, dev, subdev, 9, 8);
-
- if (scan_only)
- printf("%02lx:%02lx.%1lx Class %02x.%02x Prog %02x: %04x:%04x\n",
- bus, dev, subdev, classcode, subclass, prog, vendor, device);
-
- if (classcode == 7 && subclass == 0)
- if (unsigned long port = pci_handle_serial_dev(bus, dev,
- subdev, scan_only, board))
- return port;
- }
- }
- }
- return 0;
-}
-
-unsigned long search_pci_serial_devs(int port_idx, bool scan_only)
-{
- Serial_board board;
- if (!_search_pci_serial_devs(&board, scan_only))
- return 0;
-
- return board.get_port(port_idx);
-}
-
-namespace {
-
-class Platform_x86 : public Platform_base
-{
-public:
- bool probe() { return true; }
- void init()
- {
- // this is just a wrapper around serial.c
- // if you think this could be done better you're right...
- static L4::Uart_x86 _uart(1,1);
- _uart.startup(0);
- set_stdio_uart(&_uart);
- }
-
- void setup_memory_map(l4util_mb_info_t *mbi,
- Region_list *ram, Region_list *regions)
- {
- if (!(mbi->flags & L4UTIL_MB_MEM_MAP))
- {
- assert(mbi->flags & L4UTIL_MB_MEMORY);
- ram->add(Region::n(0, (mbi->mem_upper + 1024) << 10, ".ram",
- Region::Ram));
- }
- else
- {
- l4util_mb_addr_range_t *mmap;
- l4util_mb_for_each_mmap_entry(mmap, mbi)
- {
- unsigned long long start = (unsigned long long)mmap->addr;
- unsigned long long end = (unsigned long long)mmap->addr + mmap->size;
-
- switch (mmap->type)
- {
- case 1:
- ram->add(Region::n(start, end, ".ram", Region::Ram));
- break;
- case 2:
- case 3:
- case 4:
- regions->add(Region::n(start, end, ".BIOS", Region::Arch, mmap->type));
- break;
- case 5:
- regions->add(Region::n(start, end, ".BIOS", Region::No_mem));
- break;
- default:
- break;
- }
- }
- }
-
- regions->add(Region::n(0, 0x1000, ".BIOS", Region::Arch, 0));
- }
-};
-}
-
-REGISTER_PLATFORM(Platform_x86);
-
+++ /dev/null
-PKGDIR ?= ..
-L4DIR ?= $(PKGDIR)/../..
-
-# the default is to build the listed directories, provided that they
-# contain a Makefile. If you need to change this, uncomment the following
-# line and adapt it.
-# TARGET = idl src lib server examples doc
-
-include $(L4DIR)/mk/subdir.mk
+++ /dev/null
-PKGDIR ?= ../..
-L4DIR ?= $(PKGDIR)/../..
-
-TARGET := lib4re_main.a
-SRC_CC = __main.cc
-PC_FILENAME := l4re-main
-REQUIRES_LIBS := l4re
-CXXFLAGS := -fno-exceptions
-
-include $(L4DIR)/mk/lib.mk
-
+++ /dev/null
-/**
- * \file l4re/lib_main/src/__main.cc
- * \brief Main
- */
-/*
- * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
- * Alexander Warg <warg@os.inf.tu-dresden.de>
- * economic rights: Technische Universität Dresden (Germany)
- *
- * This file is part of TUD:OS and distributed under the terms of the
- * GNU General Public License 2.
- * Please see the COPYING-GPL-2 file for details.
- *
- * As a special exception, you may use this file as part of a free software
- * library without restriction. Specifically, if other files instantiate
- * templates or use macros or inline functions from this file, or you compile
- * this file and link it with other files to produce an executable, this
- * file does not by itself cause the resulting executable to be covered by
- * the GNU General Public License. This exception does not however
- * invalidate any other reasons why the executable file might be covered by
- * the GNU General Public License.
- */
-
-#include <stdlib.h>
-#include <l4/crtn/crt0.h>
-#include <l4/re/env>
-#include <l4/util/util.h>
-
-
-extern "C" void _exit(int code) __attribute__ ((__noreturn__, __weak__));
-#if 0
-extern "C" void __thread_doexit(int code) throw();
-extern "C" int main(int argc, char const * const*argv) throw();
-extern l4re_env_t *l4re_global_env __attribute__((weak));
-
-void
-__main(int argc, char const *argv[]) throw()
-{
- if (&l4re_global_env && argv)
- {
- l4_umword_t *auxp = (l4_umword_t*)&argv[argc] + 1;
-
- while (*auxp)
- ++auxp;
-
- ++auxp;
-
- while (*auxp)
- {
- if (*auxp == 0xf1)
- {
- l4re_global_env = (l4re_env_t*)auxp[1];
- break;
- }
- auxp += 2;
- }
- }
-
- /* call constructors */
- crt0_construction();
-
- /* call main */
- exit(main(argc, argv));
-}
-#endif
-
-void _exit(int code)
-{
- L4Re::Env const *e;
- if (l4re_global_env && (e = L4Re::Env::env()) && e->parent().is_valid())
- e->parent()->signal(0, code);
- l4_sleep_forever();
-}
-#if 0
-void __thread_doexit(int code) throw()
-{
- /*
- fast fix for linker error
- */
-}
-
-void abort(void) throw()
-{
- /* We do not provide signals, hence no SIGABRT handling here */
- exit(1);
-}
-#endif