htontcp6()

htontcp6()

概要

引数

実装

  919: Block *
  920: htontcp6(Tcp *tcph, Block *data, Tcp6hdr *ph, Tcpctl *tcb)
  921: {
  922:         int dlen;
  923:         Tcp6hdr *h;
  924:         ushort csum;
  925:         ushort hdrlen, optpad = 0;
  926:         uchar *opt;
  927: 
  928:         hdrlen = TCP6_HDRSIZE;
  929:         if(tcph->flags & SYN){
  930:                 if(tcph->mss)
  931:                         hdrlen += MSS_LENGTH;
  932:                 if(tcph->ws)
  933:                         hdrlen += WS_LENGTH;
  934:                 optpad = hdrlen & 3;
  935:                 if(optpad)
  936:                         optpad = 4 - optpad;
  937:                 hdrlen += optpad;
  938:         }
  939: 
  940:         if(data) {
  941:                 dlen = blocklen(data);
  942:                 data = padblock(data, hdrlen + TCP6_PKT);
  943:                 if(data == nil)
  944:                         return nil;
  945:         }
  946:         else {
  947:                 dlen = 0;
  948:                 data = allocb(hdrlen + TCP6_PKT + 64);        /* the 64 pad is to meet mintu's */
  949:                 if(data == nil)
  950:                         return nil;
  951:                 data->wp += hdrlen + TCP6_PKT;
  952:         }
  953: 
  954:         /* copy in pseudo ip header plus port numbers */
  955:         h = (Tcp6hdr *)(data->rp);
  956:         memmove(h, ph, TCP6_TCBPHDRSZ);
  957: 
  958:         /* compose pseudo tcp header, do cksum calculation */
  959:         hnputl(h->vcf, hdrlen + dlen);
  960:         h->ploadlen[0] = h->ploadlen[1] = h->proto = 0;
  961:         h->ttl = ph->proto;
  962: 
  963:         /* copy in variable bits */
  964:         hnputl(h->tcpseq, tcph->seq);
  965:         hnputl(h->tcpack, tcph->ack);
  966:         hnputs(h->tcpflag, (hdrlen<<10) | tcph->flags);
  967:         hnputs(h->tcpwin, tcph->wnd>>(tcb != nil ? tcb->snd.scale : 0));
  968:         hnputs(h->tcpurg, tcph->urg);
  969: 
  970:         if(tcph->flags & SYN){
  971:                 opt = h->tcpopt;
  972:                 if(tcph->mss != 0){
  973:                         *opt++ = MSSOPT;
  974:                         *opt++ = MSS_LENGTH;
  975:                         hnputs(opt, tcph->mss);
  976:                         opt += 2;
  977:                 }
  978:                 if(tcph->ws != 0){
  979:                         *opt++ = WSOPT;
  980:                         *opt++ = WS_LENGTH;
  981:                         *opt++ = tcph->ws;
  982:                 }
  983:                 while(optpad-- > 0)
  984:                         *opt++ = NOOPOPT;
  985:         }
  986: 
  987:         if(tcb != nil && tcb->nochecksum){
  988:                 h->tcpcksum[0] = h->tcpcksum[1] = 0;
  989:         } else {
  990:                 csum = ptclcsum(data, TCP6_IPLEN, hdrlen+dlen+TCP6_PHDRSIZE);
  991:                 hnputs(h->tcpcksum, csum);
  992:         }
  993: 
  994:         /* move from pseudo header back to normal ip header */
  995:         memset(h->vcf, 0, 4);
  996:         h->vcf[0] = IP_VER6;
  997:         hnputs(h->ploadlen, hdrlen+dlen);
  998:         h->proto = ph->proto;
  999: 
 1000:         return data;
 1001: }