05-24-2004
15,
0
Join Date: May 2004
Last Activity: 22 September 2004, 3:46 PM EDT
Posts: 15
Thanks Given: 0
Thanked 0 Times in 0 Posts
Yes. I'm using gcc.
Btw, I'm getting a very strange error with sendto. Here's my code. I have compiled it with gcc and I get error :
sendto:invalid argument.
int main(int argc, char *argv[])
{
struct pseudohdr {
unsigned long saddr; /* source address */
unsigned long daddr; /* dest address */
char zer0; /* zero */
unsigned char protocol; /* protocol to use */
unsigned short length; /* length of packet */
};
int one = 1, sent;
int packSize=sizeof(struct tcphdr)+sizeof(struct iphdr)
+sizeof(struct pseudohdr);
char packet[packSize]; /* Packet. */
struct sockaddr_in sin; /* Our address info structures. */
struct iphdr *ip = (struct iphdr *) packet;
struct tcphdr *tcp = (struct tcphdr *) packet + sizeof(struct iphdr);
struct pseudohdr *pseudo;
pseudo = (struct pseudohdr *) (packet + sizeof(struct iphdr) -
sizeof(struct pseudohdr));
char *remote_ip_str="128.112.139.72";
/* create the socket. */
if((sock = socket (AF_INET, SOCK_RAW, IPPROTO_TCP)) == -1) {
perror("socket"); /* Error creating socket. */
exit(-1);
}
bzero((char *) &sin, sizeof(sin));
sin.sin_port = htons(MYPORT);
if ((bind(sock, (struct sockaddr *)& sin, sizeof(sin))) < 0) {
perror("bind");
exit(1);
}
/* Tell the kernel we'll fill in the IP headers
* outselves. */
if((setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one))) < 0 )
{
perror("setsockopt");
exit(1);
}
/* Fill in the destination info. */
bzero((char *)& sin, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(MYPORT);
sin.sin_addr.s_addr = inet_addr(remote_ip_str);
bzero(packet, sizeof(packet));
/* fill in the pseudo header - this is needed to help calculate
* the checksum for the tcp segment of the packet. */
pseudo->saddr = 0;
pseudo->daddr = (u_long)inet_ntoa(sin.sin_addr);
pseudo->zer0 = 0;
pseudo->protocol = IPPROTO_TCP;
pseudo->length = htons(sizeof(struct tcphdr));
/* Fill in IP headers. */
ip->ihl = 5;
ip->version = 4;
ip->tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr);
ip->id = htons(0);
ip->saddr = 0;
ip->daddr = (u_long)inet_ntoa(sin.sin_addr);
ip->ttl = 64;
ip->protocol = IPPROTO_TCP;
ip->check = 0; /* calculate checksum later, below. */
ip->tos = 0;
ip->frag_off = 0;
/* set the checksum. */
ip->check = in_cksum((unsigned short *)ip, sizeof(struct iphdr));
/* Fill in the TCP headers. */
tcp->source = htons(MYPORT);
tcp->dest = htons(MYPORT);
tcp->seq = htons(random()); /* "random" sequence number. */
tcp->ack = 0; /* ACKnowledgement */
tcp->syn = 1;
tcp->window = htons(65535);
tcp->doff = 5;
tcp->rst = 0;
tcp->check = 0; /* calculate checksum later, below. */
tcp->psh = 0;
tcp->fin = 0;
tcp->urg = 0;
tcp->ack_seq = htons(0);
/* set the checksum. */
tcp->check = (unsigned short)in_cksum((unsigned short *)pseudo,
sizeof(struct tcphdr)+sizeof(struct pseudohdr));
//if((sent=sendto(sock, packet, ip->tot_len, 0, This didn't work either.
if((sent=sendto(sock, packet, sizeof(packet), 0,
(struct sockaddr *)&sin, sizeof(sin))) < 0 ) {
printf("sent is %d\n", sent);
perror("sendto");
exit(1);
}
printf("sent is %d\n", sent);
return(0);
}
unsigned short in_cksum(unsigned short *addr, int len) {
register int sum = 0;
u_short answer = 0;
register u_short *w = addr;
register int nleft = len;
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
if (nleft == 1) {
*(u_char *)(&answer) = *(u_char *)w ;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return(answer); /* return the checksum value. */
}