📄 miniweb.c
字号:
} if(stateptr == NULL) {#ifdef STATEFUL y = Y_NORESPONSE; tcpstate = LISTEN; printf("Stateptr == NULL, connection dropped\n");#else /* STATEFUL */ printf("Stateptr == NULL, dropping packet\n"); goto drop;#endif /* STATEFUL */ } }#ifdef STATEFUL } else { for(x = 0; x < 4; x++) { DEV_GETC(a); } }#endif /* STATEFUL */ /* Get the TCP offset and use it in the following computation. */ DEV_GETC(a); /* If this segment contains TCP data, we increase the sequence number we acknowledge by the size of this data. */ if(len - 20 - (a >> 4) * 4 > 0) { /* a is the TCP data offset. */ chksumflags = (chksumflags & CHKSUMFLAG_BYTE) | (c & 1); c = 0; ADC(seqno[3], c, (len - 20 - (a >> 4) * 4) & 0xff); ADC(seqno[2], c, (len - 20 - (a >> 4) * 4) >> 8); ADC(seqno[1], c, 0); ADC(seqno[0], c, 0); c = chksumflags & CHKSUMFLAG_CARRY;#ifdef STATEFUL y = Y_NEWDATA;#endif /* STATEFUL */ } /* TCP flags. */ DEV_GETC(a); if(a & TCP_RST) { stateptr = NULL; goto drop; }#ifdef STATEFUL /* If this is an ACK, increase congestion window by one segment (this is slow start). */ if(y == 1 && (a & TCP_ACK)) { cwnd++; }#endif /* STATEFUL */#ifndef STATEFUL if(a & TCP_SYN) { stateptr = pages[port - PORTLOW]; printf("Connection to port %d\n", port); }#endif /* STATEFUL */ if(a & TCP_SYN || a & TCP_FIN) {#ifdef STATEFUL cwnd = 1; if(a & TCP_FIN) { tcpstate = TIME_WAIT; } else if(a & TCP_SYN) { tcpstate = ESTABLISHED; tmpstateptr = stateptr = pages[port - PORTLOW]; printf("New connection from %d.%d.%d.%d:%d\n", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3], (srcport[0] << 8) + srcport[1]); inflight = 0; } y = Y_NEWDATA;#endif /* STATEFUL */ /* Increase the seqno we acknowledge by 1 */ chksumflags = (chksumflags & CHKSUMFLAG_BYTE) | (c & 1); c = 0; ADC(seqno[3], c, 1); ADC(seqno[2], c, 0); ADC(seqno[1], c, 0); ADC(seqno[0], c, 0); c = chksumflags & CHKSUMFLAG_CARRY; } /* Get the high byte of the TCP window and limit our sending rate if needed. */ DEV_GETC(a);#ifdef STATEFUL if(a < cwnd + inflight) { /* printf("Limited by receiver's window %d new window %d.\n", a, a - inflight);*/ cwnd = a - inflight; }#endif /* STATEFUL */ /* Discard the low byte of the TCP window, checksum and the urgent pointer. */ for(x = 0; x < 5; x ++) { DEV_GETC(a); } /* We continue checksumming the rest of the packet. */ /* Add the changing part of the pseudo checksum. */ ADD_CHK1(ipaddr[0]); ADD_CHK2(ipaddr[1]); ADD_CHK1(ipaddr[2]); ADD_CHK2(ipaddr[3]); ADD_CHK1((len >> 8) & 0xff); ADD_CHK2(len & 0xff); for(len = len - 40; len > 0; len--) { DEV_GETC(a); } while(c) { ADD_CHK(0); } /* printf("TCP checksum 0x%02x%02x\n", chksum[0], chksum[1]);*/ /* We compare the calculated checksum with the precalculated pseudo header checksum. If they don't match, don't send. */ if(chksum[0] == TCP_CHECK0 && chksum[1] == TCP_CHECK1) {#ifdef STATEFUL /* If y is larger than Y_RESPONSE, we should send a packet in response to the incoming one. If we are told to wait for new data (as indicated by stateptr->flag == WAIT), y has to be set to Y_NEWDATA in order for us to respond. */ if(tmpstateptr != NULL && y >= Y_RESPONSE) { if(tmpstateptr->flag != WAIT || y == Y_NEWDATA ) { nrtx = 0; tcpip_output(); } }#else /* STATEFUL */ nrtx = 0; tcpip_output();#endif /* STATEFUL */ } else { printf("Packet dropped due to failing TCP checksum.\n"); } }}/*-----------------------------------------------------------------------------------*/static voidtcpip_output(void){ txtime = timer;#ifdef STATEFUL if(tmpstateptr == NULL) { printf("tmpstateptr == NULL!\n"); return; } do { tmpptr = &(tmpstateptr->vhl);#else /* STATEFUL */ tmpptr = &(stateptr->vhl);#endif /* STATEFUL */ /* Send vhl, tos, len, id, ipoffset, ttl and protocol. */ for(x = 0; x < 10; x++) { DEV_PUT(*(tmpptr++)); } /* Fiddle with the checksum. This can be done more efficiently in assembler, where we have the option of adding with carry. */ chksum[1] = *(tmpptr++); chksum[0] = *(tmpptr++); c = 0; ADD_CHK1(ipaddr[3]); ADD_CHK2(ipaddr[2]); ADD_CHK1(ipaddr[1]); ADD_CHK2(ipaddr[0]); while(c) { ADD_CHK1(0); ADD_CHK2(0); } /* Send bytes. */ a = ~(chksum[1]); DEV_PUT(a); a = ~(chksum[0]); DEV_PUT(a); /* Send source IP address. */ for(x = 4; x > 0; x--) { DEV_PUT(*(tmpptr++)); } /* Send destination address. */ for(; x < 4; x++) { DEV_PUT(ipaddr[x]); } /* Send TCP source port. */ for(x = 0; x < 2; x++) { DEV_PUT(*(tmpptr++)); } /* Send TCP destination port. */ DEV_PUT(srcport[0]); DEV_PUT(srcport[1]); /* Send TCP sequence number. */ DEV_PUT(*(tmpptr++)); DEV_PUT(*(tmpptr++)); DEV_PUT(*(tmpptr++)); DEV_PUT(*(tmpptr++)); /* Send TCP acknowledgement number. */ DEV_PUT(seqno[0]); DEV_PUT(seqno[1]); DEV_PUT(seqno[2]); DEV_PUT(seqno[3]); /* Send offset, flags and window. */ DEV_PUT(*(tmpptr++)); DEV_PUT(*(tmpptr++)); DEV_PUT(*(tmpptr++)); DEV_PUT(*(tmpptr++)); /* Fiddle with the checksum. This can be done more efficiently in assembler, where we have the option of adding with carry. */ chksum[1] = *(tmpptr++); chksum[0] = *(tmpptr++); c = 0; ADD_CHK1(ipaddr[3]); ADD_CHK2(ipaddr[2]); ADD_CHK1(ipaddr[1]); ADD_CHK2(ipaddr[0]); ADD_CHK1(srcport[1]); ADD_CHK2(srcport[0]); ADD_CHK1(seqno[3]); ADD_CHK2(seqno[2]); ADD_CHK1(seqno[1]); ADD_CHK2(seqno[0]); while(c) { ADD_CHK1(0); ADD_CHK2(0); } /* Send bytes. */ a = ~(chksum[1]); DEV_PUT(a); a = ~(chksum[0]); DEV_PUT(a); /* Send urgent pointer. */ for(x = 0; x < 2; x++) { DEV_PUT(*(tmpptr++)); } /* Send the rest of the packet. */#ifdef STATEFUL for(x = 0; x < tmpstateptr->length; x++) { DEV_PUT(*(tmpptr++)); }#else /* STATEFUL */ for(x = 0; x < stateptr->length; x++) { DEV_PUT(*(tmpptr++)); }#endif /* STATEFUL */ DEV_DONE();#ifdef STATEFUL inflight++; tmpstateptr = tmpstateptr->next; } while(inflight < cwnd && tmpstateptr != NULL && tmpstateptr->flag != WAIT);#endif /* STATEFUL */} /*-----------------------------------------------------------------------------------*/voidminiweb_timer(void){ timer++; if(stateptr != NULL) { if(timer - txtime > 4 && stateptr->flag != WAIT) {#ifdef STATEFUL cwnd = 1; inflight = 0; tmpstateptr = stateptr;#endif /* STATEFUL */ printf("Retransmitting\n"); tcpip_output(); nrtx++; if(nrtx == 8) { miniweb_init(); } } else if(timer - txtime > 8 && stateptr->flag == WAIT) { printf("Connection dropped\n"); stateptr = NULL; miniweb_init(); } }}/*-----------------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -