?? ip.c
字號:
DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%lx netif->ip_addr 0x%lx (0x%lx, 0x%lx, 0x%lx)\n",
iphdr->dest.addr, netif->ip_addr.addr,
iphdr->dest.addr & netif->netmask.addr,
netif->ip_addr.addr & netif->netmask.addr,
iphdr->dest.addr & ~(netif->netmask.addr)));
/* interface configured? */
if(!ip_addr_isany(&(netif->ip_addr)))
{
/* unicast to this interface address? */
if(ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) ||
/* or broadcast matching this interface network address? */
(ip_addr_isbroadcast(&(iphdr->dest), &(netif->netmask)) &&
ip_addr_maskcmp(&(iphdr->dest), &(netif->ip_addr), &(netif->netmask))) ||
/* or restricted broadcast? */
ip_addr_cmp(&(iphdr->dest), IP_ADDR_BROADCAST)) {
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_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) {
DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: UDP packet to DHCP client port %u\n",
ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest)));
if (ntohs(((struct udp_hdr *)((u8_t *)iphdr + iphdrlen))->dest) == DHCP_CLIENT_PORT) {
DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: DHCP packet accepted.\n"));
netif = inp;
}
}
}
#endif /* LWIP_DHCP */
/* packet not for us? */
if(netif == NULL) {
/* packet not for us, route or discard */
DEBUGF(IP_DEBUG | DBG_TRACE | 1, ("ip_input: packet not for us.\n"));
#if IP_FORWARD
/* non-broadcast packet? */
if(!ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask))) {
/* try to forward IP packet on (other) interfaces */
ip_forward(p, iphdr, inp);
}
else
#endif /* IP_FORWARD */
{
snmp_inc_ipindiscards();
}
pbuf_free(p);
return ERR_OK;
}
#if IP_REASSEMBLY
if((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04x tot_len=%u len=%u MF=%u offset=%u), calling ip_reass()\n", ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & htons(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));
p = ip_reass(p);
if(p == NULL) {
return ERR_OK;
}
iphdr = p->payload;
}
#else /* IP_REASSEMBLY */
if((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
pbuf_free(p);
DEBUGF(IP_DEBUG | 2, ("IP packet dropped since it was fragmented (0x%x) (while IP_REASSEMBLY == 0).\n",
ntohs(IPH_OFFSET(iphdr))));
#ifdef IP_STATS
++lwip_stats.ip.opterr;
++lwip_stats.ip.drop;
#endif /* IP_STATS */
snmp_inc_ipunknownprotos();
return ERR_OK;
}
#endif /* IP_REASSEMBLY */
#if IP_OPTIONS == 0
if (iphdrlen > IP_HLEN) {
DEBUGF(IP_DEBUG | 2, ("IP packet dropped since there were IP options (while IP_OPTIONS == 0).\n"));
pbuf_free(p);
#ifdef IP_STATS
++lwip_stats.ip.opterr;
++lwip_stats.ip.drop;
#endif /* IP_STATS */
snmp_inc_ipunknownprotos();
return ERR_OK;
}
#endif /* IP_OPTIONS == 0 */
/* send to upper layers */
#if IP_DEBUG
DEBUGF(IP_DEBUG, ("ip_input: \n"));
ip_debug_print(p);
DEBUGF(IP_DEBUG, ("ip_input: p->len %d p->tot_len %d\n", p->len, p->tot_len));
#endif /* IP_DEBUG */
switch(IPH_PROTO(iphdr)) {
#if LWIP_UDP > 0
case IP_PROTO_UDP:
snmp_inc_ipindelivers();
udp_input(p, inp);
break;
#endif /* LWIP_UDP */
#if LWIP_TCP > 0
case IP_PROTO_TCP:
snmp_inc_ipindelivers();
tcp_input(p, inp);
break;
#endif /* LWIP_TCP */
case IP_PROTO_ICMP:
snmp_inc_ipindelivers();
icmp_input(p, inp);
break;
default:
/* send ICMP destination protocol unreachable unless is was a broadcast */
if(!ip_addr_isbroadcast(&(iphdr->dest), &(inp->netmask)) &&
!ip_addr_ismulticast(&(iphdr->dest))) {
p->payload = (void *)iphdr;
icmp_dest_unreach(p, ICMP_DUR_PROTO);
}
pbuf_free(p);
DEBUGF(IP_DEBUG | 2, ("Unsupported transport protocol %d\n", IPH_PROTO(iphdr)));
#ifdef IP_STATS
++lwip_stats.ip.proterr;
++lwip_stats.ip.drop;
#endif /* IP_STATS */
snmp_inc_ipunknownprotos();
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
/* ip_output_if:
*
* 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.
*/
/*-----------------------------------------------------------------------------------*/
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)
{
static struct ip_hdr *iphdr;
static u16_t ip_id = 0;
snmp_inc_ipoutrequests();
if(dest != IP_HDRINCL) {
if(pbuf_header(p, IP_HLEN)) {
DEBUGF(IP_DEBUG | 2, ("ip_output: not enough room for IP header in pbuf\n"));
#ifdef IP_STATS
++lwip_stats.ip.err;
#endif /* IP_STATS */
snmp_inc_ipoutdiscards();
return ERR_BUF;
}
iphdr = p->payload;
IPH_TTL_SET(iphdr, ttl);
IPH_PROTO_SET(iphdr, proto);
ip_addr_set(&(iphdr->dest), dest);
IPH_VHLTOS_SET(iphdr, 4, IP_HLEN / 4, 0);
IPH_LEN_SET(iphdr, htons(p->tot_len));
IPH_OFFSET_SET(iphdr, htons(IP_DF));
IPH_ID_SET(iphdr, htons(ip_id));
++ip_id;
if(ip_addr_isany(src)) {
ip_addr_set(&(iphdr->src), &(netif->ip_addr));
} else {
ip_addr_set(&(iphdr->src), src);
}
IPH_CHKSUM_SET(iphdr, 0);
IPH_CHKSUM_SET(iphdr, inet_chksum((void*)iphdr, IP_HLEN));
} else {
iphdr = p->payload;
dest = &(iphdr->dest);
}
#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
#ifdef IP_STATS
lwip_stats.ip.xmit++;
#endif /* IP_STATS */
DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%u\n", netif->name[0], netif->name[1], netif->num));
#if IP_DEBUG
ip_debug_print(p);
#endif /* IP_DEBUG */
DEBUGF(IP_DEBUG, ("netif->output()"));
return netif->output(netif, p, dest);
}
/*-----------------------------------------------------------------------------------*/
/* ip_output:
*
* Simple interface to ip_output_if. It finds the outgoing network
* interface and calls upon ip_output_if to do the actual work.
*/
/*-----------------------------------------------------------------------------------*/
err_t
ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
u8_t ttl, u8_t proto)
{
struct netif *netif;
if((netif = ip_route(dest)) == NULL) {
DEBUGF(IP_DEBUG | 2, ("ip_output: No route to 0x%lx\n", dest->addr));
#ifdef IP_STATS
++lwip_stats.ip.rterr;
#endif /* IP_STATS */
snmp_inc_ipoutdiscards();
return ERR_RTE;
}
return ip_output_if(p, src, dest, ttl, proto, netif);
}
/*-----------------------------------------------------------------------------------*/
#if IP_DEBUG
void
ip_debug_print(struct pbuf *p)
{
struct ip_hdr *iphdr = p->payload;
u8_t *payload;
payload = (u8_t *)iphdr + IP_HLEN;
DEBUGF(IP_DEBUG, ("IP header:\n"));
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(IP_DEBUG, ("|%2d |%2d | %2u | %4u | (v, hl, tos, len)\n",
IPH_V(iphdr),
IPH_HL(iphdr),
IPH_TOS(iphdr),
ntohs(IPH_LEN(iphdr))));
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(IP_DEBUG, ("| %5u |%u%u%u| %4u | (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));
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(IP_DEBUG, ("| %2u | %2u | 0x%04x | (ttl, proto, chksum)\n",
IPH_TTL(iphdr),
IPH_PROTO(iphdr),
ntohs(IPH_CHKSUM(iphdr))));
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(IP_DEBUG, ("| %3ld | %3ld | %3ld | %3ld | (src)\n",
ntohl(iphdr->src.addr) >> 24 & 0xff,
ntohl(iphdr->src.addr) >> 16 & 0xff,
ntohl(iphdr->src.addr) >> 8 & 0xff,
ntohl(iphdr->src.addr) & 0xff));
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
DEBUGF(IP_DEBUG, ("| %3ld | %3ld | %3ld | %3ld | (dest)\n",
ntohl(iphdr->dest.addr) >> 24 & 0xff,
ntohl(iphdr->dest.addr) >> 16 & 0xff,
ntohl(iphdr->dest.addr) >> 8 & 0xff,
ntohl(iphdr->dest.addr) & 0xff));
DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
}
#endif /* IP_DEBUG */
/*-----------------------------------------------------------------------------------*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -