Can you tell me what's the problem in this code of mine. I have used your checksum code. I'm not entirely sure, if it's correct or not.
Thanks.
#include<stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define MYPORT 6666
typedef struct ip_header_t {
unsigned char ihl:4,
version:4;
unsigned char tos;
unsigned short tot_len;
unsigned short id;
unsigned short frag_off;
unsigned char ttl;
unsigned char protocol;
unsigned short check;
unsigned int saddr;
unsigned int daddr;
} *iphdr;
typedef struct tcp_header_t {
unsigned short source;
unsigned short dest;
unsigned int seq;
unsigned int ack_seq;
unsigned short res1:4,
doff:4,
fin:1,
syn:1,
rst:1,
psh:1,
ack:1,
urg:1,
ece:1,
cwr:1;
unsigned short window;
unsigned short check;
unsigned short urg_ptr;
} *tcphdr;
struct pseudo {
u_long saddr;
u_long daddr;
u_char zero;
u_char protocol;
u_short length;
struct tcp\_header_t tcp;
};
/* Calculate the checksum here */
unsigned short in_cksum (unsigned short ptr, int nbytes) {
register long sum;/ assumes long == 32 bits /
u_short oddbyte;
register u_short answer;/ assumes u_short == 16 bits */
/*
* Our algorithm is simple, using a 32-bit accumulator \(sum\),
* we add sequential 16-bit words to it, and at the end, fold back
* all the carry bits from the top 16 bits into the lower 16 bits.
*/
sum = 0;
while \(nbytes > 1\) \{
sum \+= *ptr\+\+;
nbytes -= 2;
\}
/* mop up an odd byte, if necessary */
if \(nbytes == 1\) \{
oddbyte = 0;/* make sure top half is zero */
*\(\(u_char *\) & oddbyte\) = *\(u_char *\) ptr;/* one byte only */
sum \+= oddbyte;
\}
/*
* Add back carry outs from top 16 bits to low 16 bits.
*/
sum = \(sum >> 16\) \+ \(sum & 0xffff\);/* add high-16 to low-16 */
sum \+= \(sum >> 16\);/* add carry */
answer = ~sum;/* ones-complement, then truncate to 16 bits */
return \(answer\);
}
int sendpack( int s, u_long srcaddr, u_short srcport, u_long dstaddr, u_short dstport, u_long length)
{
int one=1;
unsigned short local_port, remote_port;
u_char packet[sizeof(struct ip_header_t)
+ sizeof(struct pseudo) + sizeof(struct tcp_header_t)];
struct sockaddr_in foo;
struct in_addr srcinaddr,dstinaddr;
iphdr ip = (iphdr) packet;
struct pseudo *pseudo = (struct pseudo *)(packet+ sizeof(struct ip_header_t)
+sizeof(struct tcp_header_t));
//tcphdr tcp = (tcphdr) (packet + sizeof(struct ip_header_t)
// + sizeof(struct pseudo));
tcphdr tcp;
//bzero((char *)&pseudo, sizeof(struct pseudo));
bzero(packet, sizeof(packet));
foo.sin_port = htons\(srcport\);
/* I have to bind the RAW socket to a local port. It's required here */
if \(\(bind\(s, \(struct sockaddr *\)& foo, sizeof\(foo\)\)\) < 0\) \{
perror\("bind"\);
exit\(1\);
\}
setsockopt\(s, 0, IP_HDRINCL, &one, sizeof\(one\)\);
bzero\(\(char *\)&foo,sizeof\(foo\)\);
foo.sin_family = AF_INET;
foo.sin_port = htons\(remote_port\);
foo.sin\_addr.s_addr=dstaddr;
/* building packets */
ip->ihl = 5;
ip->version = 4;
ip->tos = 0;
ip->tot_len = htons\(sizeof\(struct ip\_header_t\)\+sizeof\(struct tcp\_header_t\)\);
ip->id = 0;
ip->ttl = 64;
ip->frag_off = 0x40;
ip->protocol = IPPROTO_TCP;
ip->check = in_cksum\( \(u_short *\)ip, sizeof\( struct ip\_header_t\)\);
ip->daddr = dstaddr;
ip->saddr = srcaddr;
pseudo->saddr = srcaddr;
pseudo->daddr = dstaddr;
pseudo->zero = 0;
pseudo->protocol = IPPROTO_TCP;
pseudo->length = htons\(ntohs\(ip->tot_len\)-\(ip->ihl<<2\)\);
tcp = \(tcphdr\) \(packet \+ \(ip->ihl << 2\)\);
tcp->source = htons\(local_port\);
tcp->dest = htons\(remote_port\);
tcp->seq = rand\(\)%time\(NULL\);
tcp->ack_seq = rand\(\)%time\(NULL\);
tcp->res1 = 0;
tcp->doff = 4;
tcp->syn = 1;
tcp->check = 0;
bcopy\(tcp, &pseudo->tcp, sizeof\(struct tcp\_header_t\)\);
tcp->check = in_cksum\(\(unsigned short *\)&pseudo,
12 \+ sizeof\(struct tcp\_header_t\)\);
if\(\(sendto\(s, packet, sizeof\(packet\), 0,
\(struct sockaddr *\) &foo,sizeof\(foo\)\)\) < sizeof\(packet\)\) \{
perror\("sendto"\);
exit\(1\);
\}
printf\("Sent packet of size %d\\n", sizeof\(packet\)\);
return 0;
}
u_long resolve_name(char *hostname) {
struct hostent *host;
u_long addr;
if ((addr = inet_addr(hostname)) != -1) return addr;
if ((host = gethostbyname(hostname)) == NULL) {
fprintf(stderr,"Can not resolve name: %s\n",hostname);
exit(1);
}
bcopy(host->h_addr,&addr,host->h_length);
return addr;
}
int main(argc,argv)
int argc;
char **argv;
{
int rawfd;
int one=1;
struct in_addr srcip,dstip;
u_short srcport,dstport;
srcip.s\_addr=resolve_name\("source name"\);
srcport=MYPORT;
dstip.s\_addr=resolve_name\("dest name"\);
dstport=MYPORT;
if \(\(rawfd=socket\(PF\_INET,SOCK\_RAW,IPPROTO_TCP\)\)<0\) \{
perror\("RawSocket:"\);
exit\(1\);
\}
if \(setsockopt\(rawfd,IPPROTO\_IP,IP_HDRINCL,&one,sizeof\(one\)\)<0\) \{
perror\("SetSockOpt:"\);
close\(rawfd\);
exit\(1\);
\}
printf\("sending packet from: %s:%i ",inet_ntoa\(srcip\),srcport\);
printf\("to %s:%i\\n",inet_ntoa\(dstip\),dstport\);
sendpack\(rawfd,srcip.s\_addr,srcport,dstip.s_addr,dstport,0\);
close\(rawfd\);
return 0;
}