Posted: Thu Mar 16, 2006 3:27 am Post subject: linux raw packets (c)
Hi, I don't know how to get this code to compile in FC4. I'm using GCC, I'm not sure what includes I need.
c:
#define P 2123 /* lets flood the sendmail port */
unsignedshort/* this function generates header checksums */
csum (unsignedshort *buf, int nwords) { unsignedlong sum;
for(sum = 0; nwords > 0; nwords--)
sum += *buf++;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return ~sum;
}
int
main (void) { int s = socket (PF_INET, SOCK_RAW, IPPROTO_TCP); /* open raw socket */ char datagram[4096]; /* this buffer will contain ip header, tcp header,
and payload. we'll point an ip header structure
at its beginning, and a tcp header structure after
that to write the header values into it */ struct ip *iph = (struct ip *) datagram;
struct tcphdr *tcph = (struct tcphdr *) datagram + sizeof(struct ip);
struct sockaddr_in sin;
/* the sockaddr_in containing the dest. address is used
in sendto() to determine the datagrams path */
sin.sin_family = AF_INET;
sin.sin_port = htons (P);/* you byte-order >1byte header values to network
byte order (not needed on big endian machines) */
sin.sin_addr.s_addr = inet_addr ("127.0.0.1");
memset (datagram, 0, 4096); /* zero out the buffer */
/* we'll now fill in the ip/tcp header values, see above for explanations */
iph->ip_hl = 5;
iph->ip_v = 4;
iph->ip_tos = 0;
iph->ip_len = sizeof(struct ip) + sizeof(struct tcphdr); /* no payload */
iph->ip_id = htonl (54321); /* the value doesn't matter here */
iph->ip_off = 0;
iph->ip_ttl = 255;
iph->ip_p = 6;
iph->ip_sum = 0; /* set it to 0 before computing the actual checksum later */
iph->ip_src.s_addr = inet_addr ("1.2.3.4");/* SYN's can be blindly spoofed */
iph->ip_dst.s_addr = sin.sin_addr.s_addr;
tcph->th_sport = htons (1234); /* arbitrary port */
tcph->th_dport = htons (P);
tcph->th_seq = random ();/* in a SYN packet, the sequence is a random */
tcph->th_ack = 0;/* number, and the ack sequence is 0 in the 1st packet */
tcph->th_x2 = 0;
tcph->th_off = 0; /* first and only tcp segment */
tcph->th_flags = TH_SYN; /* initial connection request */
tcph->th_win = htonl (65535); /* maximum allowed window size */
tcph->th_sum = 0;/* if you set a checksum to zero, your kernel's IP stack
should fill in the correct checksum during transmission */
tcph->th_urp = 0;
/* finally, it is very advisable to do a IP_HDRINCL call, to make sure
that the kernel knows the header is included in the data, and doesn't
insert its own header into the packet before our data */
{/* lets do it the ugly way.. */ int one = 1;
constint *val = &one;
if(setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof(one)) < 0) printf("Warning: Cannot set HDRINCL!\n");
}
while(1) { if(sendto (s, /* our socket */
datagram, /* the buffer containing headers and data */
iph->ip_len, /* total length of our datagram */ 0, /* routing flags, normally always 0 */ (struct sockaddr *) &sin, /* socket addr, just like in */ sizeof(sin)) < 0)/* a normal send() */ printf("error\n");
else printf(".");
}
return0;
}
Sponsor Sponsor
Andy
Posted: Thu Mar 16, 2006 8:34 am Post subject: (No subject)
I didnt have time to go through your entire code, but why are you declaring your main as void, and still returning 0? and why are there brackets around this?
{ /* lets do it the ugly way.. */
int one = 1;
const int *val = &one;
if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0)
printf ("Warning: Cannot set HDRINCL!\n");
}
Justin_
Posted: Thu Mar 16, 2006 1:05 pm Post subject: (No subject)
its not my code, i'm reading a raw packet tutorial so it was simply copy and paste. I figured the code would be correct...
Oh well, thanks Andy.
wtd
Posted: Thu Mar 16, 2006 1:15 pm Post subject: (No subject)
As far as I can tell, it is correct. It's just tremendously ugly. But then, it is C.
Is there some reason you couldn't do this in a language with a higher level networking library?
Justin_
Posted: Thu Mar 16, 2006 1:29 pm Post subject: (No subject)
Yes, I am learning raw sockets. I want to know every detail that goes into a packet. I have a decent non-programming understanding as it is, but now I want to put that understanding into some application via programming.
the line:
Int main (void)
You say its correct. I don't understand it, and it appears neither did Andy. But I do see that main is returning an int.
And about compiling it, I've never compiled anything in linux before so I need major help there.
wtd
Posted: Thu Mar 16, 2006 1:36 pm Post subject: (No subject)
code:
int main(void)
Declares a function named main that returns int, and has a void parameter list.
I suggest you read "man gcc".
Justin_
Posted: Thu Mar 16, 2006 1:52 pm Post subject: (No subject)
Could int main (void) be written int main() then?
I've done a fair share of reading in my day and the only thing it taught me is much more than I needed to know. It would be more pleasurable for me if I could get a straight cut to the chase, but I understand if you don't want to help. I'm just going to have to post my question at other forums
wtd
Posted: Thu Mar 16, 2006 1:57 pm Post subject: (No subject)
Justin_ wrote:
Could int main (void) be written int main() then?
Yes.
Justin_ wrote:
I've done a fair share of reading in my day and the only thing it taught me is much more than I needed to know. It would be more pleasurable for me if I could get a straight cut to the chase, but I understand if you don't want to help. I'm just going to have to post my question at other forums
I could write a huge long tutorial on how to use all of GCC's options, but then it'd be as long as the manpage, and probably not as well written.
And honestly, the subject doesn't interest me that much.
And if you need custom include paths, use the -I (capital i) option. If you need to include a library, use the -l (lowercase L) option.
Sponsor Sponsor
Justin_
Posted: Thu Mar 16, 2006 2:02 pm Post subject: (No subject)
yeah that's pretty much all i needed. But, what includes do I need for a program like this in linux.
P.S. I tried using a -I in windows because one of my header files was in a different directory, I gave it an absolute path and it didn't work. The syntax I used was like this:
-If:\Documents and Settings\
is it possible to give -I an absolute path?
wtd
Posted: Thu Mar 16, 2006 2:07 pm Post subject: (No subject)
GCC may be interacting poorly with the way Windows handles filesystems. *nix-y environments have a single root, but Windows has multiple roots. This is a fairly fundamental schism. I would suggest sticking to Linux for now so that you can focus on the networking voodoo, rather than unbreaking Windows.
wtd
Posted: Thu Mar 16, 2006 2:10 pm Post subject: (No subject)
You may wish to try:
code:
-lsocket
Justin_
Posted: Thu Mar 16, 2006 2:21 pm Post subject: (No subject)
Yeah I just noticed the file system issues with -I on windows. It loses you when you put a space.
In linux i tried to compile the above code like this:
code:
gcc rawSocket.c -lsocket
But a number of things came up undeclared.
md
Posted: Thu Mar 16, 2006 2:25 pm Post subject: (No subject)
I'm curious as to why you'd want to learn this stuff anyways. Unless your writing a IP stack or implementing a new protocol this level of code is nearly useless.
The reason the socket libraries exist is to make dealing with sockets easy
wtd
Posted: Thu Mar 16, 2006 2:44 pm Post subject: (No subject)
Justin_ wrote:
Yeah I just noticed the file system issues with -I on windows. It loses you when you put a space.
Surround paths with spaces with quotes.
Justin_
Posted: Thu Mar 16, 2006 6:45 pm Post subject: (No subject)
Cornflake wrote:
I'm curious as to why you'd want to learn this stuff anyways.
Because I'm curious as to how sockets work.
wtd wrote:
Surround paths with spaces with quotes.
Right, thanks.
So I guess you don't know the includes it needs? And here's another question for you. In windows ctrl-c = copy. Is there a keyboard short cut like this for linux? I'm guessing no, because it depends on the current thread that's running.