Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 linux raw packets (c)
Index -> Programming, C++ -> C++ Help
Goto page 1, 2  Next
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
Justin_




PostPosted: 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;
}
Sponsor
Sponsor
Sponsor
sponsor
Andy




PostPosted: 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_




PostPosted: 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




PostPosted: 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. Wink

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




PostPosted: 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




PostPosted: 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_




PostPosted: 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 Smile
wtd




PostPosted: 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 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.
Sponsor
Sponsor
Sponsor
sponsor
Justin_




PostPosted: 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




PostPosted: 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




PostPosted: Thu Mar 16, 2006 2:10 pm   Post subject: (No subject)

You may wish to try:

code:
-lsocket
Justin_




PostPosted: 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




PostPosted: 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 Wink
wtd




PostPosted: 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_




PostPosted: 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.
Display posts from previous:   
   Index -> Programming, C++ -> C++ Help
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 2  [ 28 Posts ]
Goto page 1, 2  Next
Jump to:   


Style:  
Search: