Я пытался создать отправитель TCP-пакетов в C с помощью следующего кодаTCP пакетов ошибок Sender
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
int main(void){
char buffer[1024];
int packetsize[100];
char* source_ip = "192.168.2.1";
struct sockaddr_in serv;
struct iphdr *iph;
struct tcphdr *tcph;
int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
serv.sin_family = AF_INET;
serv.sin_port = htons(80);
serv.sin_addr.s_addr = inet_addr ("8.8.8.8");
struct tcp_pseudo
{
uint32_t src_addr;
uint32_t dst_addr;
uint8_t zero;
uint8_t proto;
uint16_t length;
} pseudohead;
struct help_checksum
{
struct tcp_pseudo pshd;
struct tcphdr tcphd;
char tcpdata[1024];
} tcp_chk_construct;
// Create Packet Header
iph.ihl = 5;
iph.version = 4;
iph.tos = 0;
iph.tot_len = sizeof(struct iphdr) + packetsize;
iph.id = rand_cmwc();
iph.frag_off = 0;
iph.ttl = MAXTTL;
iph.protocol = IPPROTO_TCP;
iph.check = 0;
iph.saddr = source_ip;
iph.daddr = serv.sin_addr.s_addr;
// Create TCP Header
tcph.source = htons (1234);
tcph.dest = htons (80);
tcph.seq = 0;
tcph.ack_seq = 0;
tcph.doff = 5;
tcph.fin=0;
tcph.syn=1;
tcph.rst=0;
tcph.psh=0;
tcph.ack=0;
tcph.urg=0;
tcph.window = htons (5840);
tcph.check = 0;
tcph.urg_ptr = 0;
pseudohead.src_addr = iph->saddr;
pseudohead.dst_addr = iph->daddr;
pseudohead.dummy = 0;
pseudohead.proto = iph->protocol;
pseudohead.length = htons(sizeof(struct tcphdr) + packetsize);
tcp_chk_construct.pshd = pseudohead;
tcp_chk_construct.tcphd = tcph;
memcpy(tcp_chk_construct.tcpdata, buffer, packetsize);
tcph->check = in_cksum((unsigned short *) &tcp_chk_construct,
sizeof(struct tcp_pseudo) + sizeof(struct tcphdr) + packetsize);
memcpy(packetsize, (char *) &iph
, sizeof(iphdr));
memcpy(packetsize + sizeof(iphdr), (char *) &tcph
, sizeof(tcphdr));
memcpy(packetsize + sizeof(iphdr) + sizeof(tcphdr, buffer, packetsize);
if (sendto (sockfd, /* our socket */
buffer, /* the buffer containing headers and data */
iph->tot_len, /* total length of our datagram */
0, /* routing flags, normally always 0 */
(struct sockaddr *) &serv, /* socket addr, just like in */
sizeof (serv)) < 0) /* a normal send() */
{
printf ("error\n");
}
else
{
printf ("Packet Send \n");
}
}
Я использую netinet/ip.h
и netinet/tcp.h
сделать фактический пакет TCP, но я получаю следующие ошибки при компиляции мой код:
error: variable has incomplete type 'struct iphdr'
struct iphdr iph;
forward declaration of 'struct iphdr'
struct iphdr iph;
error: invalid application of 'sizeof' to an incomplete type 'struct iphdr'
iph.tot_len = sizeof(struct iphdr) + packetsize;
error: no member named 'source' in 'struct tcphdr'
tcph.source = htons (1234);
error: no member named 'dest' in 'struct tcphdr'
tcph.dest = htons (80);
и так далее для заголовка tcp.
struct iphdr * iph; struct tcphdr * tcph; Эти указатели используются без выделения. – cm161
@ cm161 как бы исправить эту ошибку – user243
Изучив ваш код w.r.t. * iph и * tcph, они не нужны в качестве указателя. memcpy() вызовы с & iph и & tcph идут не так, если вы собираетесь использовать его в качестве указателей (после правильного выделения). Строковый экземпляр будет работать нормально. Определите экземпляры как struct iphdr iph; struct tcphdr tcph; Затем замените все места, где iph-> и tcph-> разыменование используется с iph. и tcph. (замена -> с. оператором). Надеемся, что вы включили исправления, предложенные @Haris. – cm161