Hello, Since last mail I studied TCP/IP stack source, and I concluded that for problem of length becoming uncorrect when making SYN-ACK packet,only possible cause is tp->t_flags is become un-correct value in tcp_input() for generating SYN-ACK packet. Of cource I know it's caused by my wrong coding or my cofiguration. But I beseech you to help me discover the cause of it. As I said in previous mail, tp->t_flags was 0xA1 when jumped tcp_output at 2345 line in tcp_input.c. tcp_input() 2342: #endif 2343: m_freem(m); 2344: tp->t_flags |= TF_ACKNOW; 2345: (void) tcp_output(tp); Is this value is correct for sending SYN-ACK packet to host. Would you please let me know correct value. If by any chance, this is uncorrect would you enligten me what do you think cause of malfunction ? When I searched tp->t_flags topics in mailing list, I found next topic titled "Re: SYN problem with new TCP/IP stack". In Sun, 12 Feb 2006 mail Mr.Grant Edwards wrote next sentences. > So, the ACK that's required by the TCP RFC is never sent (the > SYN packet is just ignored). So, the host just sits there and > sends SYNs. Then the host's owner gets annoyed and calls > customer support, yadda yadda, and here were are. > Adding the following code immediately after the drop: label at > line 2398 fixes the problem. > if (tp->t_flags & TF_ACKNOW) > (void)tcp_output(tp); I checked my tcp_input.c(CVS current version),it does not include above code. To be on the safe side,I send my tcp_input.c version,would you please check it is updated to include above operation ? One more question: I still not checked auto_negotiation,but is there any chance tp->t_flags becomes bad value when auto_negotiation mal-functioed ? I most earnetly beseech you to help me. Thank you in advance. Masahiro Ariga ----- Original Message ----- From: "ariga masahiro" To: "Gary Thomas" ; "Alok Singh" ; "Andrew Lunn" Cc: Sent: Tuesday, November 13, 2007 10:13 AM Subject: Re: [ECOS] Can't Connect,TCP CHECKSUM INCORRECT > Hello, > > I setted break point at ether_demux()'s 599 line in if_ethersubr.c and > dumped mbuf data > when received SYN packet from host and was confirmed its content is just > as same as > Ethereal captured data and also mh_len is correct. > > ether_demux(ifp, eh, m) 596-601 lines > case ETHERTYPE_IP: > if (ipflow_fastforward(m)) > return; > schednetisr(NETISR_IP); > inq = &ipintrq; > break; > > Ethereal captured SYN-packet > host[172.16.1.28]-->target[172.16.1.200] TCP SYN packet > 0000 00 40 31 08 01 00 00 15 c5 6d 23 f0 08 00 45 00 > 0010 00 30 09 fb 40 00 80 06 95 c8 ac 10 01 1c ac 10 > 0020 01 c8 04 d2 22 42 10 7d 2c a0 00 00 00 00 70 02 > 0030 ff ff c3 e9 00 00 02 04 05 b4 01 01 04 02 > > mbuf dumped data > {m_hdr={mh_next=*00000000,mh_nextpkt=*00000000,mh_data=*8C092EAC,mh_len=0x30,mh_type=0x1,mh_flags=0x2}, > 8C092EAC 45 00 00 30 09 FB 40 00 > 8C092EB4 80 06 95 C8 AC 10 01 1C > 8C092EBC AC 10 01 C8 04 D2 22 42 > 8C092EC4 10 7D 2C A0 00 00 00 00 > 8C092ECC 70 02 FF FF C3 E9 00 00 > 8C092ED4 02 04 05 B4 01 01 04 02 > 8C092EDC 00 40 31 08 01 00 08 06 > 8C092EE4 00 01 08 00 06 04 00 01 > > Also I setted break point at eth_drv_send()'s line 748 in eth_drv.c. > and dumped sg_list in which sending packet is reserved. > This is just before jumping to lan91cxx_send(). > > eth_drv.c > eth_drv_send(struct ifnet *ifp) > 746: // Tell hardware to send this packet > 747: if ( sg_len ) > break 748: (sc->funs->send)(sc, sg_list, sg_len, total_len, > (unsigned long)m0); > > sg_list > [0] = {buf=0x8C0928AE,len=0x36} > [1] = {buf=0x8,len=0x8C0816B4} > [2] = {buf=0x0,len=0x8C081248} > 8C0928AE 00 15 C5 6D 23 F0 00 40 > 8C0928B6 31 08 01 00 08 00 45 00 > 8C0928BE 00 28 00 02 40 00 40 06 > 8C0928C6 DF C9 AC 10 01 C8 AC 10 > 8C0928CE 01 1C 22 42 05 3F 11 0E > 8C0928D6 A5 2E 78 6A D4 5B 60 12 > 8C0928DE 44 70 D5 D5 00 00 02 04 > 8C0928E6 05 B4 00 00 00 00 00 00 > > And I confirmed that already at this point IP packet > length(line-3,column-1,2) is contradicting > with TCP data-offset(line-6,column-7). Both lengths too short. > > Thus I think it proves that my current trouble(=SYN-ACK becomes Malformed > Packet) > is not concerned with hardware byte swapping.(at least directry) > I think it is caused by something else. > > I beseech you to consider again without attention to hardware byte > swapping. > > I re-post my trouble or question from 11/6/2007 mail. >> After exchanged commands in UDP, >> host begins to TCP Connect and send SYN packet >> to our target.Target receives SYN packet and tries to >> send back SYN-ACK but that packet becomes Malformed packet. >> SYN-ACK packet is never recieved by host. >> Please refer to Ethereal txt log file I sent before. >> >> I captured TCP connection between Windows PCs, >> and compared SYN - SYNACK packets between Windows PCs log and >> host-target >> log, >> and I noticed there are some incomprehensible points. >> >> Below is from Ethereal Capture log >> >> Windows<-->Windows -- no problem >> PC-client[172.16.1.28]<-->PC-server[172.16.1.21] >> [172.16.1.28]-->[172.16.1.21] >> SYN-Packet >> 00 10 a4 8a 8a ce 00 15 c5 6d 23 f0 08 00 45 00 >> 00 30 30 b8 40 00 80 06 6f be ac 10 01 1c ac 10 >> 01 15 04 c5 04 21 33 5d c7 c1 00 00 00 00 70 02 >> ff ff 24 c9 00 00 02 04 05 b4 01 01 04 02 >> [172.16.1.21]-->[172.16.1.28] >> SYN-ACK-Packet >> 00 15 c5 6d 23 f0 00 10 a4 8a 8a ce 08 00 45 00 >> 00 30 16 2a 40 00 80 06 8a 4c ac 10 01 15 ac 10 >> 01 1c 04 21 04 c5 20 08 8f 1b 33 5d c7 c2 70 12 >> 44 70 31 24 00 00 02 04 05 b4 01 01 04 02 >> ========================================================= >> cygwin<-->eCos -- SYN-ACK [CHECKSUM INCORRECT][Malformed packet] >> host-client[172.16.1.28]<-->target-server[172.16.1.200] >> [172.16.1.28]-->[172.16.1.200] >> SYN-Packet >> 00 40 31 08 01 00 00 15 c5 6d 23 f0 08 00 45 00 >> 00 30 35 81 40 00 80 06 6a 42 ac 10 01 1c ac 10 >> 01 c8 05 1e 22 42 a6 39 a9 dc 00 00 00 00 70 02 >> ff ff b0 a4 00 00 02 04 05 b4 01 01 04 02 >> [172.16.1.200]-->[172.16.1.28] >> SYN-ACK-Packet >> 00 15 c5 6d 23 f0 00 40 31 08 01 00 08 00 45 00 >> 00 28 00 02 40 00 40 06 df c9 ac 10 01 c8 ac 10 >> 01 1c 22 42 05 1e 17 7a 85 37 a6 39 a9 dd 60 12 >> 44 70 ec 30 00 00 00 00 00 00 00 00 >> >> My incomprehensible points are, >> about Target's SYN-ACK-Packet, >> 1. paket length in IP header(=0028 line-2,colum-1,2) indicates >> length from top of IP header(line-1,colum-15) to last of packet, >> but 0028(=40d) counts to line-4,colum-6,there are 6 bytes surplus. >> 2. data offset bits(=6 line-3,colum-15) indicates there are 4*6=24bytes >> from top of TCP header(line-3,colum-3) to last of packet. >> But 24 counts to line-4,colum-10,there are 2 bytes surplus. >> And there is a contradiction between paket length in IP header and >> TCP >> data offset bits. >> 3. option part of SYN packet(00 00 02 04 05 b4 01 01 04 02) changed to >> (00 >> 00 00 00 00 00 00 00) >> in Target's SYN-ACK-Packet. >> >> Please, could you enlighten me what is cause of this phenomenon ? >> >> By the way,I calculated checksum mannually and confirmed they are all >> correct. >> >> I only changed coding in retrieving data in BigEndian as I reported to >> you. >> I think others are resolved by Macros of bigendian. >> >> Currently when building, Resolve conflicts dialog appears like below. >> >> Resolve conflicts >> Item Conflict Property >> CYGPKG_POSIX_CLOCKS Unsatisfied Requires >> CYGBLD_ISO_STRUCTTIMEVAL_HEADER=="" >> CYGPKG_FILEIO_FNMATCH Unsatisfied Requires >> CYGBLD_ISO_FNMATCH__HEADER=="" >> Proposed Solutions: >> Item Value >> x CYGBLD_ISO_FNMATCH__HEADER Enabled, >> x CYGBLD_ISO_STRUCTTIMEVAL_HEADER Enabled, >> > > I think at least my next observation is connected with my problem. > This is from 11/08/2007 mail. >> I traced tcp_output function. >> It looks to me, at tcp_output's next points, append option part. > >> line 688-691 >> if (optlen) { >> bcopy(opt, th + 1, optlen); >> th->th_off = (sizeof (struct tcphdr) + optlen) >> 2; >> } > >> Although peer sent 8 bytes option,optlen was 4. >> >> Also it looks to me, in generating SYN-ACK packet, at next switch >> sentence, >> case (TH_SYN|TH_ACK) context should be executed. >> But it all passed out these block, never entered if sentence(line 445) >> block. >> At that time tp->t_flags was 0xA1,flags was 0x12. >> >> line 445-510 >> /* >> * Send `CC-family' options if our side wants to use them (TF_REQ_CC), >> * options are allowed (!TF_NOOPT) and it's not a RST. >> */ >> if ((tp->t_flags & (TF_REQ_CC|TF_NOOPT)) == TF_REQ_CC && >> (flags & TH_RST) == 0) { >> switch (flags & (TH_SYN|TH_ACK)) { >> /* >> * This is a normal ACK, send CC if we received CC before >> * from our peer. >> */ >> case TH_ACK: >> if (!(tp->t_flags & TF_RCVD_CC)) >> break; >> /*FALLTHROUGH*/ >> >> /* >> * We can only get here in T/TCP's SYN_SENT* state, when >> * we're a sending a non-SYN segment without waiting for >> * the ACK of our SYN. A check above assures that we only >> * do this if our peer understands T/TCP. >> */ >> case 0: >> opt[optlen++] = TCPOPT_NOP; >> opt[optlen++] = TCPOPT_NOP; >> opt[optlen++] = TCPOPT_CC; >> opt[optlen++] = TCPOLEN_CC; >> *(u_int32_t *)&opt[optlen] = htonl(tp->cc_send); >> >> optlen += 4; >> break; >> >> /* >> * This is our initial SYN, check whether we have to use >> * CC or CC.new. >> */ >> case TH_SYN: >> opt[optlen++] = TCPOPT_NOP; >> opt[optlen++] = TCPOPT_NOP; >> opt[optlen++] = tp->t_flags & TF_SENDCCNEW ? >> TCPOPT_CCNEW : TCPOPT_CC; >> opt[optlen++] = TCPOLEN_CC; >> *(u_int32_t *)&opt[optlen] = htonl(tp->cc_send); >> optlen += 4; >> break; >> >> /* >> * This is a SYN,ACK; send CC and CC.echo if we received >> * CC from our peer. >> */ >> case (TH_SYN|TH_ACK): >> if (tp->t_flags & TF_RCVD_CC) { >> opt[optlen++] = TCPOPT_NOP; >> opt[optlen++] = TCPOPT_NOP; >> opt[optlen++] = TCPOPT_CC; >> opt[optlen++] = TCPOLEN_CC; >> *(u_int32_t *)&opt[optlen] = >> htonl(tp->cc_send); >> optlen += 4; >> opt[optlen++] = TCPOPT_NOP; >> opt[optlen++] = TCPOPT_NOP; >> opt[optlen++] = TCPOPT_CCECHO; >> opt[optlen++] = TCPOLEN_CC; >> *(u_int32_t *)&opt[optlen] = >> htonl(tp->cc_recv); >> optlen += 4; >> } >> break; >> } >> } > > Please help me to resolve problem. > Thank you in advance.