📄 uip.lst
字号:
805 6 goto tcp_send_finack;
806 6
807 6 }
808 5 }
809 4 } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
810 4 /* If there was no need for a retransmission, we poll the
811 4 application for new data. */
812 4 uip_flags = UIP_POLL;
813 4 UIP_APPCALL();
814 4 goto appsend;
815 4 }
816 3 }
817 2 goto drop;
818 2 }
819 1 #if UIP_UDP
if(flag == UIP_UDP_TIMER) {
if(uip_udp_conn->lport != 0) {
uip_conn = NULL;
uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
uip_len = uip_slen = 0;
uip_flags = UIP_POLL;
UIP_UDP_APPCALL();
goto udp_send;
} else {
goto drop;
}
}
#endif
833 1
834 1 /* This is where the input processing starts. */
835 1 UIP_STAT(++uip_stat.ip.recv);
836 1
837 1 /* Start of IP input header processing code. */
838 1
839 1 #if UIP_CONF_IPV6
/* Check validity of the IP header. */
if((BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */
UIP_STAT(++uip_stat.ip.drop);
UIP_STAT(++uip_stat.ip.vhlerr);
UIP_LOG("ipv6: invalid version.");
goto drop;
}
#else /* UIP_CONF_IPV6 */
848 1 /* Check validity of the IP header. */
849 1 if(BUF->vhl != 0x45) { /* IP version and header length. */
850 2 UIP_STAT(++uip_stat.ip.drop);
851 2 UIP_STAT(++uip_stat.ip.vhlerr);
852 2 UIP_LOG("ip: invalid version or header length.");
853 2 goto drop;
854 2 }
855 1 #endif /* UIP_CONF_IPV6 */
856 1
857 1 /* Check the size of the packet. If the size reported to us in
858 1 uip_len is smaller the size reported in the IP header, we assume
859 1 that the packet has been corrupted in transit. If the size of
860 1 uip_len is larger than the size reported in the IP packet header,
C51 COMPILER V7.06 UIP 05/02/2009 15:51:22 PAGE 15
861 1 the packet has been padded and we set uip_len to the correct
862 1 value.. */
863 1
864 1 if((BUF->len[0] << 8) + BUF->len[1] <= uip_len) {
865 2 uip_len = (BUF->len[0] << 8) + BUF->len[1];
866 2 #if UIP_CONF_IPV6
uip_len += 40; /* The length reported in the IPv6 header is the
length of the payload that follows the
header. However, uIP uses the uip_len variable
for holding the size of the entire packet,
including the IP header. For IPv4 this is not a
problem as the length field in the IPv4 header
contains the length of the entire packet. But
for IPv6 we need to add the size of the IPv6
header (40 bytes). */
#endif /* UIP_CONF_IPV6 */
877 2 } else {
878 2 UIP_LOG("ip: packet shorter than reported in IP header.");
879 2 goto drop;
880 2 }
881 1
882 1 #if !UIP_CONF_IPV6
883 1 /* Check the fragment flag. */
884 1 if((BUF->ipoffset[0] & 0x3f) != 0 ||
885 1 BUF->ipoffset[1] != 0) {
886 2 #if UIP_REASSEMBLY
uip_len = uip_reass();
if(uip_len == 0) {
goto drop;
}
#else /* UIP_REASSEMBLY */
892 2 UIP_STAT(++uip_stat.ip.drop);
893 2 UIP_STAT(++uip_stat.ip.fragerr);
894 2 UIP_LOG("ip: fragment dropped.");
895 2 goto drop;
896 2 #endif /* UIP_REASSEMBLY */
897 2 }
898 1 #endif /* UIP_CONF_IPV6 */
899 1
900 1 if(uip_ipaddr_cmp(uip_hostaddr, all_zeroes_addr)) {
901 2 /* If we are configured to use ping IP address configuration and
902 2 hasn't been assigned an IP address yet, we accept all ICMP
903 2 packets. */
904 2 #if UIP_PINGADDRCONF && !UIP_CONF_IPV6
905 2 if(BUF->proto == UIP_PROTO_ICMP) {
906 3 UIP_LOG("ip: possible ping config packet received.");
907 3 goto icmp_input;
908 3 } else {
909 3 UIP_LOG("ip: packet dropped since no address assigned.");
910 3 goto drop;
911 3 }
912 2 #endif /* UIP_PINGADDRCONF */
913 2
914 2 } else {
915 2 /* If IP broadcast support is configured, we check for a broadcast
916 2 UDP packet, which may be destined to us. */
917 2 #if UIP_BROADCAST
DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum());
if(BUF->proto == UIP_PROTO_UDP &&
uip_ipaddr_cmp(BUF->destipaddr, all_ones_addr)
/*&&
uip_ipchksum() == 0xffff*/) {
C51 COMPILER V7.06 UIP 05/02/2009 15:51:22 PAGE 16
goto udp_input;
}
#endif /* UIP_BROADCAST */
926 2
927 2 /* Check if the packet is destined for our IP address. */
928 2 #if !UIP_CONF_IPV6
929 2 if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr)) {
930 3 UIP_STAT(++uip_stat.ip.drop);
931 3 goto drop;
932 3 }
933 2 #else /* UIP_CONF_IPV6 */
/* For IPv6, packet reception is a little trickier as we need to
make sure that we listen to certain multicast addresses (all
hosts multicast address, and the solicited-node multicast
address) as well. However, we will cheat here and accept all
multicast packets that are sent to the ff02::/16 addresses. */
if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr) &&
BUF->destipaddr[0] != HTONS(0xff02)) {
UIP_STAT(++uip_stat.ip.drop);
goto drop;
}
#endif /* UIP_CONF_IPV6 */
945 2 }
946 1
947 1 #if !UIP_CONF_IPV6
948 1 if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header
949 2 checksum. */
950 2 UIP_STAT(++uip_stat.ip.drop);
951 2 UIP_STAT(++uip_stat.ip.chkerr);
952 2 UIP_LOG("ip: bad checksum.");
953 2 goto drop;
954 2 }
955 1 #endif /* UIP_CONF_IPV6 */
956 1
957 1 if(BUF->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so,
958 2 proceed with TCP input
959 2 processing. */
960 2 goto tcp_input;
961 2 }
962 1
963 1 #if UIP_UDP
if(BUF->proto == UIP_PROTO_UDP) {
goto udp_input;
}
#endif /* UIP_UDP */
968 1
969 1 #if !UIP_CONF_IPV6
970 1 /* ICMPv4 processing code follows. */
971 1 if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from
972 2 here. */
973 2 UIP_STAT(++uip_stat.ip.drop);
974 2 UIP_STAT(++uip_stat.ip.protoerr);
975 2 UIP_LOG("ip: neither tcp nor icmp.");
976 2 goto drop;
977 2 }
978 1
979 1 #if UIP_PINGADDRCONF
980 1 icmp_input:
981 1 #endif /* UIP_PINGADDRCONF */
982 1 UIP_STAT(++uip_stat.icmp.recv);
983 1
984 1 /* ICMP echo (i.e., ping) processing. This is simple, we only change
C51 COMPILER V7.06 UIP 05/02/2009 15:51:22 PAGE 17
985 1 the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP
986 1 checksum before we return the packet. */
987 1 if(ICMPBUF->type != ICMP_ECHO) {
988 2 UIP_STAT(++uip_stat.icmp.drop);
989 2 UIP_STAT(++uip_stat.icmp.typeerr);
990 2 UIP_LOG("icmp: not icmp echo.");
991 2 goto drop;
992 2 }
993 1
994 1 /* If we are configured to use ping IP address assignment, we use
995 1 the destination IP address of this ping packet and assign it to
996 1 ourself. */
997 1 #if UIP_PINGADDRCONF
998 1 if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) {
999 2 uip_hostaddr[0] = BUF->destipaddr[0];
1000 2 uip_hostaddr[1] = BUF->destipaddr[1];
1001 2 }
1002 1 #endif /* UIP_PINGADDRCONF */
1003 1
1004 1 ICMPBUF->type = ICMP_ECHO_REPLY;
1005 1
1006 1 if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) {
1007 2 ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1;
1008 2 } else {
1009 2 ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8);
1010 2 }
1011 1
1012 1 /* Swap IP addresses. */
1013 1 uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
1014 1 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
1015 1
1016 1 UIP_STAT(++uip_stat.icmp.sent);
1017 1 goto send;
1018 1
1019 1 /* End of IPv4 input header processing code. */
1020 1 #else /* !UIP_CONF_IPV6 */
/* This is IPv6 ICMPv6 processing code. */
DEBUG_PRINTF("icmp6_input: length %d\n", uip_len);
if(BUF->proto != UIP_PROTO_ICMP6) { /* We only allow ICMPv6 packets from
here. */
UIP_STAT(++uip_stat.ip.drop);
UIP_STAT(++uip_stat.ip.protoerr);
UIP_LOG("ip: neither tcp nor icmp6.");
goto drop;
}
UIP_STAT(++uip_stat.icmp.recv);
/* If we get a neighbor solicitation for our address we should send
a neighbor advertisement message back. */
if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) {
if(uip_ipaddr_cmp(ICMPBUF->icmp6data, uip_hostaddr)) {
if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) {
/* Save the sender's address in our neighbor list. */
uip_neighbor_add(ICMPBUF->srcipaddr, &(ICMPBUF->options[2]));
}
/* We should now send a neighbor advertisement back to where the
neighbor solicication came from. */
C51 COMPILER V7.06 UIP 05/02/2009 15:51:22 PAGE 18
ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT;
ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */
ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0;
uip_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr);
uip_ipaddr_copy(ICMPBUF->srcipaddr, uip_hostaddr);
ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS;
ICMPBUF->options[1] = 1; /* Options length, 1 = 8 bytes. */
memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr));
ICMPBUF->icmpchksum = 0;
ICMPBUF->icmpchksum = ~uip_icmp6chksum();
goto send;
}
goto drop;
} else if(ICMPBUF->type == ICMP6_ECHO) {
/* ICMP echo (i.e., ping) processing. This is simple, we only
change the ICMP type from ECHO to ECHO_REPLY and update the
ICMP checksum before we return the packet. */
ICMPBUF->type = ICMP6_ECHO_REPLY;
uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
ICMPBUF->icmpchksum = 0;
ICMPBUF->icmpchksum = ~uip_icmp6chksum();
UIP_STAT(++uip_stat.icmp.sent);
goto send;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -