📄 uip.c
字号:
goto drop;
}
#if UIP_UDP
if(flag == UIP_UDP_TIMER) {
if(uip_udp_conn->lport != 0) {
uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
uip_len = uip_slen = 0;
uip_flags = UIP_POLL;
UIP_UDP_APPCALL();
goto udp_send;
}
else {
goto drop;
}
}
#endif
/* This is where the input processing starts. */
UIP_STAT(++uip_stat.ip.recv);
/* Start of IPv4 input header processing code. */
/* Check validity of the IP header. */
if(BUF->vhl != 0x45) { /* IP version and header length. */
UIP_STAT(++uip_stat.ip.drop);
UIP_STAT(++uip_stat.ip.vhlerr);
UIP_LOG("ip: invalid version or header length.");
goto drop;
}
/* Check the size of the packet. If the size reported to us in
uip_len doesn't match the size reported in the IP header, there
has been a transmission error and we drop the packet. */
if(BUF->len[0] != (uip_len >> 8)) { /* IP length, high byte. */
uip_len = (uip_len & 0xff) | (BUF->len[0] << 8);
}
if(BUF->len[1] != (uip_len & 0xff)) { /* IP length, low byte. */
uip_len = (uip_len & 0xff00) | BUF->len[1];
}
/* Check the fragment flag. */
if((BUF->ipoffset[0] & 0x3f) != 0 || BUF->ipoffset[1] != 0) {
#if UIP_REASSEMBLY
uip_len = uip_reass();
if(uip_len == 0) {
goto drop;
}
#else
UIP_STAT(++uip_stat.ip.drop);
UIP_STAT(++uip_stat.ip.fragerr);
UIP_LOG("ip: fragment dropped.");
goto drop;
#endif /* UIP_REASSEMBLY */
}
/* If we are configured to use ping IP address configuration and
hasn't been assigned an IP address yet, we accept all ICMP
packets. */
#if UIP_PINGADDRCONF
if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
if(BUF->proto == UIP_PROTO_ICMP) {
UIP_LOG("ip: possible ping config packet received.");
goto icmp_input;
}
else {
UIP_LOG("ip: packet dropped since no address assigned.");
goto drop;
}
}
#endif /* UIP_PINGADDRCONF */
/* Check if the packet is destined for our IP address. */
if(BUF->destipaddr[0] != uip_hostaddr[0]) {
UIP_STAT(++uip_stat.ip.drop);
UIP_LOG("ip: packet not for us.");
goto drop;
}
if(BUF->destipaddr[1] != uip_hostaddr[1]) {
UIP_STAT(++uip_stat.ip.drop);
UIP_LOG("ip: packet not for us.");
goto drop;
}
#if 0
// IP checksum is wrong through Netgear DSL router
if (uip_ipchksum() != 0xffff) { /* Compute and check the IP header
checksum. */
UIP_STAT(++uip_stat.ip.drop);
UIP_STAT(++uip_stat.ip.chkerr);
UIP_LOG("ip: bad checksum.");
goto drop;
}
#endif
if(BUF->proto == UIP_PROTO_TCP) /* Check for TCP packet. If so, jump
to the tcp_input label. */
goto tcp_input;
#if UIP_UDP
if(BUF->proto == UIP_PROTO_UDP)
goto udp_input;
#endif /* UIP_UDP */
if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from
here. */
UIP_STAT(++uip_stat.ip.drop);
UIP_STAT(++uip_stat.ip.protoerr);
UIP_LOG("ip: neither tcp nor icmp.");
goto drop;
}
#if UIP_PINGADDRCONF
icmp_input:
#endif
UIP_STAT(++uip_stat.icmp.recv);
/* ICMP echo (i.e., ping) processing. This is simple, we only change
the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP
checksum before we return the packet. */
if(ICMPBUF->type != ICMP_ECHO) {
UIP_STAT(++uip_stat.icmp.drop);
UIP_STAT(++uip_stat.icmp.typeerr);
UIP_LOG("icmp: not icmp echo.");
goto drop;
}
/* If we are configured to use ping IP address assignment, we use
the destination IP address of this ping packet and assign it to
ourself. */
#if UIP_PINGADDRCONF
if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
uip_hostaddr[0] = BUF->destipaddr[0];
uip_hostaddr[1] = BUF->destipaddr[1];
}
#endif /* UIP_PINGADDRCONF */
ICMPBUF->type = ICMP_ECHO_REPLY;
if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
}
else {
ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
}
/* Swap IP addresses. */
tmp16 = BUF->destipaddr[0];
BUF->destipaddr[0] = BUF->srcipaddr[0];
BUF->srcipaddr[0] = tmp16;
tmp16 = BUF->destipaddr[1];
BUF->destipaddr[1] = BUF->srcipaddr[1];
BUF->srcipaddr[1] = tmp16;
UIP_STAT(++uip_stat.icmp.sent);
goto send;
/* End of IPv4 input header processing code. */
#if UIP_UDP
/* UDP input processing. */
udp_input:
/* UDP processing is really just a hack. We don't do anything to the
UDP/IP headers, but let the UDP application do all the hard
work. If the application sets uip_slen, it has a packet to
send. */
#if UIP_UDP_CHECKSUMS
if(uip_udpchksum() != 0xffff) {
UIP_STAT(++uip_stat.udp.drop);
UIP_STAT(++uip_stat.udp.chkerr);
UIP_LOG("udp: bad checksum.");
goto drop;
}
#endif /* UIP_UDP_CHECKSUMS */
/* Demultiplex this UDP packet between the UDP "connections". */
for(uip_udp_conn = &uip_udp_conns[0]; uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];++uip_udp_conn) {
if(uip_udp_conn->lport != 0 &&
UDPBUF->destport == uip_udp_conn->lport &&
( uip_udp_conn->rport == 0 ||
UDPBUF->srcport == uip_udp_conn->rport ) &&
BUF->srcipaddr[0] == uip_udp_conn->ripaddr[0] &&
BUF->srcipaddr[1] == uip_udp_conn->ripaddr[1]) {
goto udp_found;
}
}
goto drop;
udp_found:
uip_len = uip_len - 28;
uip_appdata = &uip_buf[UIP_LLH_LEN + 28];
uip_flags = UIP_NEWDATA;
uip_slen = 0;
UIP_UDP_APPCALL();
udp_send:
if(uip_slen == 0) {
goto drop;
}
uip_len = uip_slen + 28;
BUF->len[0] = (uip_len >> 8);
BUF->len[1] = (uip_len & 0xff);
BUF->proto = UIP_PROTO_UDP;
UDPBUF->udplen = HTONS(uip_slen + 8);
UDPBUF->udpchksum = 0;
#if UIP_UDP_CHECKSUMS
/* Calculate UDP checksum. */
UDPBUF->udpchksum = ~(uip_udpchksum());
if(UDPBUF->udpchksum == 0) {
UDPBUF->udpchksum = 0xffff;
}
#endif /* UIP_UDP_CHECKSUMS */
BUF->srcport = uip_udp_conn->lport;
BUF->destport = uip_udp_conn->rport;
BUF->srcipaddr[0] = uip_hostaddr[0];
BUF->srcipaddr[1] = uip_hostaddr[1];
BUF->destipaddr[0] = uip_udp_conn->ripaddr[0];
BUF->destipaddr[1] = uip_udp_conn->ripaddr[1];
uip_appdata = &uip_buf[UIP_LLH_LEN + 40];
goto ip_send_nolen;
#endif /* UIP_UDP */
/* TCP input processing. */
tcp_input:
UIP_STAT(++uip_stat.tcp.recv);
/* Start of TCP input header processing code. */
#if 1 // FIXME
if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP
checksum. */
UIP_STAT(++uip_stat.tcp.drop);
UIP_STAT(++uip_stat.tcp.chkerr);
UIP_LOG("tcp: bad checksum.");
goto drop;
}
#endif
/* Demultiplex this segment. */
/* First check any active connections. */
for(uip_connr = &uip_conns[0]; uip_connr < &uip_conns[UIP_CONNS]; ++uip_connr) {
if(uip_connr->tcpstateflags != CLOSED &&
BUF->destport == uip_connr->lport &&
BUF->srcport == uip_connr->rport &&
BUF->srcipaddr[0] == uip_connr->ripaddr[0]&&
BUF->srcipaddr[1] == uip_connr->ripaddr[1]) {
goto found;
}
}
/* If we didn't find and active connection that expected the packet,
either this packet is an old duplicate, or this is a SYN packet
destined for a connection in LISTEN. If the SYN flag isn't set,
it is an old packet and we send a RST. */
if((BUF->flags & TCP_CTL) != TCP_SYN)
goto reset;
tmp16 = BUF->destport;
/* Next, check listening connections. */
for(c = 0; c < UIP_LISTENPORTS; ++c) {
if(tmp16 == uip_listenports[c])
goto found_listen;
}
/* No matching connection found, so we send a RST packet. */
UIP_STAT(++uip_stat.tcp.synrst);
reset:
/* We do not send resets in response to resets. */
if(BUF->flags & TCP_RST)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -