📄 uip.lst
字号:
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;
} else {
DEBUG_PRINTF("Unknown icmp6 message type %d\n", ICMPBUF->type);
UIP_STAT(++uip_stat.icmp.drop);
UIP_STAT(++uip_stat.icmp.typeerr);
UIP_LOG("icmp: unknown ICMP message.");
goto drop;
}
/* End of IPv6 ICMP processing. */
#endif /* !UIP_CONF_IPV6 */
1108 1
C51 COMPILER V9.00 UIP 02/08/2010 20:58:31 PAGE 19
1109 1 #if UIP_UDP
1110 1 /* UDP input processing. */
1111 1 udp_input:
1112 1 /* UDP processing is really just a hack. We don't do anything to the
1113 1 UDP/IP headers, but let the UDP application do all the hard
1114 1 work. If the application sets uip_slen, it has a packet to
1115 1 send. */
1116 1 #if UIP_UDP_CHECKSUMS
uip_len = uip_len - UIP_IPUDPH_LEN;
uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
if(UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff) {
UIP_STAT(++uip_stat.udp.drop);
UIP_STAT(++uip_stat.udp.chkerr);
UIP_LOG("udp: bad checksum.");
goto drop;
}
#else /* UIP_UDP_CHECKSUMS */
1126 1 uip_len = uip_len - UIP_IPUDPH_LEN;
1127 1 #endif /* UIP_UDP_CHECKSUMS */
1128 1
1129 1 /* Demultiplex this UDP packet between the UDP "connections". */
1130 1 for(uip_udp_conn = &uip_udp_conns[0];
1131 1 uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS];
1132 1 ++uip_udp_conn) {
1133 2 /* If the local UDP port is non-zero, the connection is considered
1134 2 to be used. If so, the local port number is checked against the
1135 2 destination port number in the received packet. If the two port
1136 2 numbers match, the remote port number is checked if the
1137 2 connection is bound to a remote port. Finally, if the
1138 2 connection is bound to a remote IP address, the source IP
1139 2 address of the packet is checked. */
1140 2 if(uip_udp_conn->lport != 0 &&
1141 2 UDPBUF->destport == uip_udp_conn->lport &&
1142 2 (uip_udp_conn->rport == 0 ||
1143 2 UDPBUF->srcport == uip_udp_conn->rport ||
1144 2 uip_udp_conn->rport == HTONS(69)) &&
1145 2 (uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) ||
1146 2 uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_ones_addr) ||
1147 2 uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) {
1148 3 goto udp_found;
1149 3 }
1150 2 }
1151 1 UIP_LOG("udp: no matching connection found");
1152 1 goto drop;
1153 1
1154 1 udp_found:
1155 1 #if UIP_TCP
1156 1 uip_conn = NULL;
1157 1 #endif /* UIP_TCP */
1158 1 uip_flags = UIP_NEWDATA;
1159 1 uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
1160 1 uip_slen = 0;
1161 1 UIP_UDP_APPCALL();
1162 1 udp_send:
1163 1 if(uip_slen == 0) {
1164 2 goto drop;
1165 2 }
1166 1 uip_len = uip_slen + UIP_IPUDPH_LEN;
1167 1
1168 1 #if UIP_CONF_IPV6
/* For IPv6, the IP length field does not include the IPv6 IP header
length. */
C51 COMPILER V9.00 UIP 02/08/2010 20:58:31 PAGE 20
BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
#else /* UIP_CONF_IPV6 */
1174 1 BUF->len[0] = (uip_len >> 8);
1175 1 BUF->len[1] = (uip_len & 0xff);
1176 1 #endif /* UIP_CONF_IPV6 */
1177 1
1178 1 BUF->ttl = uip_udp_conn->ttl;
1179 1 BUF->proto = UIP_PROTO_UDP;
1180 1
1181 1 UDPBUF->udplen = HTONS(uip_slen + UIP_UDPH_LEN);
1182 1 UDPBUF->udpchksum = 0;
1183 1
1184 1 BUF->srcport = uip_udp_conn->lport;
1185 1 BUF->destport = uip_udp_conn->rport;
1186 1
1187 1 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
1188 1 uip_ipaddr_copy(BUF->destipaddr, uip_udp_conn->ripaddr);
1189 1
1190 1 uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
1191 1
1192 1 #if UIP_UDP_CHECKSUMS
/* Calculate UDP checksum. */
UDPBUF->udpchksum = ~(uip_udpchksum());
if(UDPBUF->udpchksum == 0) {
UDPBUF->udpchksum = 0xffff;
}
#endif /* UIP_UDP_CHECKSUMS */
1199 1
1200 1 goto ip_send_nolen;
1201 1 #endif /* UIP_UDP */
1202 1
1203 1 /* TCP input processing. */
1204 1 #if UIP_TCP
1205 1 tcp_input:
1206 1 UIP_STAT(++uip_stat.tcp.recv);
1207 1
1208 1 /* Start of TCP input header processing code. */
1209 1
1210 1 if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP
1211 2 checksum. */
1212 2 UIP_STAT(++uip_stat.tcp.drop);
1213 2 UIP_STAT(++uip_stat.tcp.chkerr);
1214 2 UIP_LOG("tcp: bad checksum.");
1215 2 goto drop;
1216 2 }
1217 1
1218 1
1219 1 /* Demultiplex this segment. */
1220 1 /* First check any active connections. */
1221 1 for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1];
1222 1 ++uip_connr) {
1223 2 if(uip_connr->tcpstateflags != UIP_CLOSED &&
1224 2 BUF->destport == uip_connr->lport &&
1225 2 BUF->srcport == uip_connr->rport &&
1226 2 uip_ipaddr_cmp(BUF->srcipaddr, uip_connr->ripaddr)) {
1227 3 goto found;
1228 3 }
1229 2 }
1230 1
1231 1 /* If we didn't find and active connection that expected the packet,
1232 1 either this packet is an old duplicate, or this is a SYN packet
C51 COMPILER V9.00 UIP 02/08/2010 20:58:31 PAGE 21
1233 1 destined for a connection in LISTEN. If the SYN flag isn't set,
1234 1 it is an old packet and we send a RST. */
1235 1 if((BUF->flags & TCP_CTL) != TCP_SYN) {
1236 2 goto reset;
1237 2 }
1238 1
1239 1 tmp16 = BUF->destport;
1240 1 /* Next, check listening connections. */
1241 1 for(c = 0; c < UIP_LISTENPORTS; ++c) {
1242 2 if(tmp16 == uip_listenports[c])
1243 2 goto found_listen;
1244 2 }
1245 1
1246 1 /* No matching connection found, so we send a RST packet. */
1247 1 UIP_STAT(++uip_stat.tcp.synrst);
1248 1 reset:
1249 1
1250 1 /* We do not send resets in response to resets. */
1251 1 if(BUF->flags & TCP_RST) {
1252 2 goto drop;
1253 2 }
1254 1
1255 1 UIP_STAT(++uip_stat.tcp.rst);
1256 1
1257 1 BUF->flags = TCP_RST | TCP_ACK;
1258 1 uip_len = UIP_IPTCPH_LEN;
1259 1 BUF->tcpoffset = 5 << 4;
1260 1
1261 1 /* Flip the seqno and ackno fields in the TCP header. */
1262 1 c = BUF->seqno[3];
1263 1 BUF->seqno[3] = BUF->ackno[3];
1264 1 BUF->ackno[3] = c;
1265 1
1266 1 c = BUF->seqno[2];
1267 1 BUF->seqno[2] = BUF->ackno[2];
1268 1 BUF->ackno[2] = c;
1269 1
1270 1 c = BUF->seqno[1];
1271 1 BUF->seqno[1] = BUF->ackno[1];
1272 1 BUF->ackno[1] = c;
1273 1
1274 1 c = BUF->seqno[0];
1275 1 BUF->seqno[0] = BUF->ackno[0];
1276 1 BUF->ackno[0] = c;
1277 1
1278 1 /* We also have to increase the sequence number we are
1279 1 acknowledging. If the least significant byte overflowed, we need
1280 1 to propagate the carry to the other bytes as well. */
1281 1 if(++BUF->ackno[3] == 0) {
1282 2 if(++BUF->ackno[2] == 0) {
1283 3 if(++BUF->ackno[1] == 0) {
1284 4 ++BUF->ackno[0];
1285 4 }
1286 3 }
1287 2 }
1288 1
1289 1 /* Swap port numbers. */
1290 1 tmp16 = BUF->srcport;
1291 1 BUF->srcport = BUF->destport;
1292 1 BUF->destport = tmp16;
1293 1
1294 1 /* Swap IP addresses. */
C51 COMPILER V9.00 UIP 02/08/2010 20:58:31 PAGE 22
1295 1 uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr);
1296 1 uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr);
1297 1
1298 1 /* And send out the RST packet! */
1299 1 goto tcp_send_noconn;
1300 1
1301 1 /* This label will be jumped to if we matched the incoming packet
1302 1 with a connection in LISTEN. In that case, we should create a new
1303 1 connection and send a SYNACK in return. */
1304 1 found_listen:
1305 1 /* First we check if there are any connections avaliable. Unused
1306 1 connections are kept in the same table as used connections, but
1307 1 unused ones have the tcpstate set to CLOSED. Also, connections in
1308 1 TIME_WAIT are kept track of and we'll use the oldest one if no
1309 1 CLOSED connections are found. Thanks to Eddie C. Dost for a very
1310 1 nice algorithm for the TIME_WAIT search. */
1311 1 uip_connr = 0;
1312 1 for(c = 0; c < UIP_CONNS; ++c) {
1313 2 if(uip_conns[c].tcpstateflags == UIP_CLOSED) {
1314 3 uip_connr = &uip_conns[c];
1315 3 break;
1316 3 }
1317 2 if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) {
1318 3 if(uip_connr == 0 ||
1319 3 uip_conns[c].timer > uip_connr->timer) {
1320 4 uip_connr = &uip_conns[c];
1321 4 }
1322 3 }
1323 2 }
1324 1
1325 1 if(uip_connr == 0) {
1326 2 /* All connections are used already, we drop packet and hope that
1327 2 the remote end will retransmit the packet at a time when we
1328 2 have more spare connections. */
1329 2 UIP_STAT(++uip_stat.tcp.syndrop);
1330 2 UIP_LOG("tcp: found no unused connections.");
1331 2 goto drop;
1332 2 }
1333 1 uip_conn = uip_connr;
1334 1
1335 1 /* Fill in the necessary fields for the new connection. */
1336 1 uip_connr->rto = uip_connr->timer = UIP_RTO;
1337 1 uip_connr->sa = 0;
1338 1 uip_connr->sv = 4;
1339 1 uip_connr->nrtx = 0;
1340 1 uip_connr->lport = BUF->destport;
1341 1 uip_connr->rport = BUF->srcport;
1342 1 uip_ipaddr_copy(uip_connr->ripaddr, BUF->srcipaddr);
1343 1 uip_connr->tcpstateflags = UIP_SYN_RCVD;
1344 1
1345 1 uip_connr->snd_nxt[0] = iss[0];
1346 1 uip_connr->snd_nxt[1] = iss[1];
1347 1 uip_connr->snd_nxt[2] = iss[2];
1348 1 uip_connr->snd_nxt[3] = iss[3];
1349 1 uip_connr->len = 1;
1350 1
1351 1 /* rcv_nxt should be the seqno from the incoming packet + 1. */
1352 1 uip_connr->rcv_nxt[3] = BUF->seqno[3];
1353 1 uip_connr->rcv_nxt[2] = BUF->seqno[2];
1354 1 uip_connr->rcv_nxt[1] = BUF->seqno[1];
1355 1 uip_connr->rcv_nxt[0] = BUF->seqno[0];
1356 1 uip_add_rcv_nxt(1);
C51 COMPILER V9.00 UIP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -