Computer Science Canada

linux raw packets (c)

Author:  Justin_ [ 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 */

unsigned short    /* this function generates header checksums */
csum (unsigned short *buf, int nwords)
{
  unsigned long 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;

  iph->ip_sum = csum ((unsigned short *) datagram, iph->ip_len >> 1);

/* 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;
    const int *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 (".");
    }

  return 0;
}

Author:  Andy [ Thu Mar 16, 2006 8:34 am ]
Post 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");
}

Author:  Justin_ [ Thu Mar 16, 2006 1:05 pm ]
Post 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.

Author:  wtd [ Thu Mar 16, 2006 1:15 pm ]
Post subject: 

As far as I can tell, it is correct. It's just tremendously ugly. But then, it is C. Wink

Is there some reason you couldn't do this in a language with a higher level networking library?

Author:  Justin_ [ Thu Mar 16, 2006 1:29 pm ]
Post 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.

Author:  wtd [ Thu Mar 16, 2006 1:36 pm ]
Post 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".

Author:  Justin_ [ Thu Mar 16, 2006 1:52 pm ]
Post 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 Smile

Author:  wtd [ Thu Mar 16, 2006 1:57 pm ]
Post 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 Smile


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.

The basic compilation:

code:
gcc -o output_file source_file1.c source_file2.c source_fileN.c


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.

Author:  Justin_ [ Thu Mar 16, 2006 2:02 pm ]
Post 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?

Author:  wtd [ Thu Mar 16, 2006 2:07 pm ]
Post 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.

Author:  wtd [ Thu Mar 16, 2006 2:10 pm ]
Post subject: 

You may wish to try:

code:
-lsocket

Author:  Justin_ [ Thu Mar 16, 2006 2:21 pm ]
Post 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.

Author:  md [ Thu Mar 16, 2006 2:25 pm ]
Post 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 Wink

Author:  wtd [ Thu Mar 16, 2006 2:44 pm ]
Post 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.

Author:  Justin_ [ Thu Mar 16, 2006 6:45 pm ]
Post 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.

Author:  md [ Thu Mar 16, 2006 6:50 pm ]
Post subject: 

Justin_ wrote:
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.


What editor are you using? There is almost certainly copy functionality; though the keys might be different.

Author:  Justin_ [ Thu Mar 16, 2006 8:33 pm ]
Post subject: 

emacs, but I was really asking for a universal copy shortcut, for shell and everything. I didn't think there was one. When I think of linux I think of the most user unfriendly environment imaginable. The one good thing about commercial software is it adheres to standards.

Author:  wtd [ Thu Mar 16, 2006 8:37 pm ]
Post subject: 

So, why use emacs? Just edit in something like gedit and then use the shell to compile. You can have your cake and eat it too.

Author:  Justin_ [ Fri Mar 17, 2006 3:05 am ]
Post subject: 

I don't understand what I'd be gaining if I edited in Gedit but thanks anyway.

Author:  wtd [ Fri Mar 17, 2006 3:08 am ]
Post subject: 

A decent GUI environment? The keyboard shortcuts you're used to?

Author:  Justin_ [ Fri Mar 17, 2006 4:16 am ]
Post subject: 

What keyboard shortcuts? I specifically asked if there were any. Wow.

Author:  wtd [ Fri Mar 17, 2006 4:41 am ]
Post subject: 

Gedit is a GUI text editor. It's standard issue with recent versions of the Gnome desktop environment, and from screenshots, it appears you're using that.

Remember, the GUI and the command-line are not entirely separate. They both deal with the same filesystem.

Author:  Justin_ [ Fri Mar 17, 2006 4:15 pm ]
Post subject: 

I know this. I'm sorry you're confused what my question actually is.

My questions that remain unanswered are:

What headers do I need to compile that raw socket code example in linux?

And on the side:

In linux, are their keyboard shortcuts for copy and paste like ctrl-c in windows?

Author:  wtd [ Fri Mar 17, 2006 4:18 pm ]
Post subject: 

There weren't include directives in this code you downloaded? Because before it seemed you were asking about which libraries you needed to link against, and now it seems you're asking about headers. These are very different things.

Author:  md [ Fri Mar 17, 2006 4:29 pm ]
Post subject: 

Justin_ wrote:
In linux, are their keyboard shortcuts for copy and paste like ctrl-c in windows?


As I tried to point out it depends on what program you are using. If your using something like gedit then the keys are crtl-c and crtl-v just like windows. If your using something else try reading the man pages or using google.

Author:  Justin_ [ Fri Mar 17, 2006 5:35 pm ]
Post subject: 

That sucks Cornflake. Truly, I mean imagine having to learn new hotkeys for every single program just because people can't devise one standard.

Well before I phrased the question "what includes do I need" and I figured that was explicit enough considering include is the keyword for including headers.

For example:

#include <iostream>

what do I include for this program in linux?

Author:  md [ Sat Mar 18, 2006 10:39 am ]
Post subject: 

Justin_ wrote:
That sucks Cornflake. Truly, I mean imagine having to learn new hotkeys for every single program just because people can't devise one standard.

Well before I phrased the question "what includes do I need" and I figured that was explicit enough considering include is the keyword for including headers.

For example:

#include <iostream>

what do I include for this program in linux?


No, it makes sense when you look at the differences between linux and windows. On linux there are many many character/console based programs, and in those programs ctrl+whatever is almost always an important escape sequence that can't be over-written, or is better overwritten with something more inline with what hte original escape sequence is supposed to do. For instance ctrl-c causes most programs to exit. Making it instead copy text would just confuse habitual linux users. When you use graphical tools like gedit or any of the other X based editors copy and paste are almost always the same as their windows counter-parts as escape sequences aren't as integral in a graphical enviroment.

If you don't want to take the time to learn the commands for emacs then use something else. Complaining because you are lazy seems pretty poor to me.

As for the include I would imagine that whatever tutorials you were using would tell you. Perhaps reading them instead of just swiping the code might be a good idea. 'Course it's really not that hard to guess it's something like sockets.h

Author:  Justin_ [ Sat Mar 18, 2006 1:22 pm ]
Post subject: 

lol, you win, i'll stop posting here. It's getting to be a bad experience for me with all the bull shit.


: