Отправка большого tcp-пакета по сегментам

212
02 июля 2017, 15:02

Пишу программу для перехвата tcp-трафика в корпоративной сети, при котором клиенту отправляется обратно tcp-пакет с html-страницей (какая-нибудь информация).

Набросал кривой/черновой вариант функции отправки этого tcp-пакета (обратно клиенту), используя код из стороннего проекта, т.к. не могу найти более лучшего.

void sendpkt(struct ip &fromIp,struct ip &toIp,int fromPort,int toPort,uint32_t acknum,uint32_t seqnum,int fReset,int fPsh) {
 std::string dt="данные на 3000 байт";
 char datagram[4096],*data,*pseudogram=NULL;
 memset(datagram,0,sizeof(datagram));
 struct sockaddr_in sin;
 struct iphdr *iph=(struct iphdr *)datagram;
 struct tcphdr *tcph=(struct tcphdr *)(datagram+sizeof(struct iphdr));
 data=(char *)tcph+sizeof(struct tcphdr);
 sin.sin_family=AF_INET;
 sin.sin_port=htons(toPort);
 sin.sin_addr.s_addr=((in_addr *)toIp.addr())->s_addr;
 iph->ihl=5;
 iph->version=4;
 iph->tos=0;
 iph->id=htons(random());
 iph->frag_off=0;
 iph->ttl=250;
 iph->protocol=IPPROTO_TCP;
 iph->check=0;
 iph->saddr=((in_addr *)fromIp.addr())->s_addr;
 iph->daddr=sin.sin_addr.s_addr;
 iph->check=0;
 tcph->source=htons(fromPort);
 tcph->dest=htons(toPort);
 tcph->seq=acknum;
 tcph->doff=5;
 tcph->syn=0;
 tcph->rst=fReset;
 tcph->psh=fPsh;
 if (fReset) {tcph->ack=0; tcph->ack_seq=0; tcph->fin=0;}
 else {tcph->ack=1; tcph->ack_seq=seqnum;}
 tcph->urg=0;
 tcph->window=htons(5840);
 tcph->check=0;
 tcph->urg_ptr=0;
 struct pseudo_header psh;
 psh.source_address=((in_addr *)fromIp.addr())->s_addr;
 psh.dest_address=sin.sin_addr.s_addr;
 psh.placeholder=0;
 psh.protocol=IPPROTO_TCP;
 int buflen=dt.length();
 size_t sendlen=MIN(buflen,1024);
 size_t remlen=buflen;
 const char *curpos=dt.c_str();
 while (remlen>0) {
  memcpy(data,curpos,sendlen);
  iph->tot_len=sizeof(struct iphdr)+sizeof(struct tcphdr)+sendlen;
  psh.tcp_length=htons(sizeof(struct tcphdr)+sendlen);
  int psize=sizeof(struct pseudo_header)+sizeof(struct tcphdr)+sendlen;
  pseudogram=(char*)calloc(1,psize);
  memcpy(pseudogram,(char*) &psh,sizeof(struct pseudo_header));
  memcpy(pseudogram+sizeof(struct pseudo_header),tcph,sizeof(struct tcphdr)+sendlen);
  tcph->check=csum((unsigned short*)pseudogram,psize);
  if (remlen==sendlen && !fReset) {tcph->fin=1;} else {tcph->fin=0;}
  ssize_t len=sendto(this->s,datagram,iph->tot_len,0,(struct sockaddr *)&sin,sizeof(sin));
  if (len<0) {remlen=0;}
  if (pseudogram) {free(pseudogram);}
  tcph->seq=htonl(ntohl(tcph->seq)+sendlen);
  curpos+=(len-(sizeof(struct iphdr)+sizeof(struct tcphdr)));
  remlen-=(len-(sizeof(struct iphdr)+sizeof(struct tcphdr)));
  sendlen=MIN(remlen,1024);
 }
}

Клиент получает первый фрагмент и пишет об ошибки чтения данных. По dump трафика вижу все пакеты и в них верные seq. Содержимое в пакетах есть. Не могу понять в чем я ошибся. Может какой-то флаг забыл?

READ ALSO
DirectX функция D3DXVec3Normalize, нормализация вектора

DirectX функция D3DXVec3Normalize, нормализация вектора

Начал изучать графику, изучаю функции матбиблиотеки dx, и одна функция отказывается работать

253
cpprestsdk(casablanca) json преобразовать в вектор байтов

cpprestsdk(casablanca) json преобразовать в вектор байтов

Всем здрасте, использую cpprestsdk для напиания http клиента, стоит задача преобразовать такой json в std::vector<unsigned char>

261
смена содержимого по клику на кнопку

смена содержимого по клику на кнопку

Подскажите как при клике по кнопке

248