Link to home
Start Free TrialLog in
Avatar of philuxe
philuxe

asked on

checksum problem with raw socket

hi all I writing a a nmap like softare in C#.

All works fine except the checkusm on TCP header, checksum on IP header is correct accordint to network sniffer !!
So i send a tcp packet with the SYN flag I dont get any answer because packet is rejected due to its checksum error ...

I dont understand very well why I have to use a pseudoheader structure while buildint TCP packet even if I know TCP checksum is calculated on a part of IP header.

Here is my source code :

##################################
unsigned short in_checksum(u_short * addr, int len)
{
      register int nleft = len;
      register int sum= 0;
      u_short answer=0;
      
      while (nleft >1)
            {
            sum += *addr++;
            nleft -=2;
            }
      
      if (nleft ==1)
            {
            *(u_char *) (&answer) = *(u_char *) addr;
            sum += answer;
            }

      sum = (sum >> 16) + (sum + 0xffff);
        sum += (sum >> 16);
        answer = ~sum;
      return (answer);
}






void connexion (char *cible, int portdest)
{
      struct sockaddr_in destination, from;
      struct iphdr *ip, *iprecu;
        struct tcphdr *tcp, *tcprecu;
       
      struct pseudohdr {
            unsigned long saddr;
            unsigned long daddr;
            char useless;
            unsigned char protocol;
            unsigned short length;
      };

      
      struct pseudohdr pseudo;
      
      
      struct timeval tv_timeout; /*gestion du timeout*/
        char *paquet;
        char *recev_buffer;
      
      int sock, r, retval, nbr;
      
      /* liste de fd utilisee en interne par select */
      fd_set fdsr;      


      int from_len=sizeof(from);
        recev_buffer = malloc(sizeof(struct iphdr) + sizeof(struct tcphdr)) ;
        paquet = malloc(sizeof(struct iphdr) + sizeof(struct tcphdr)) ;
      
      
        ip = (struct iphdr *)paquet;
        tcp = (struct tcphdr *) (paquet + sizeof (struct iphdr));
      /*pseudo = (struct pseudohdr *) (paquet + sizeof(struct iphdr) - sizeof(struct pseudohdr));*/
      
      memset(paquet, 0, sizeof(struct iphdr) + sizeof(struct tcphdr));
      memset(recev_buffer, 0, sizeof(struct iphdr) + sizeof(struct tcphdr));
      

      
      destination.sin_family = AF_INET;
      /*destination.sin_port = htons(portdest);*/ /*on le remplit dans la strcuture*/
      
/*Conversion de la chaine de caractere cible passee en argument a la fonction
en adresse rezo et stockage du resultat dans la structure de connexion*/
      inet_aton (cible, &destination.sin_addr);
      
      if ((sock = socket(PF_INET, SOCK_RAW, IPPROTO_TCP)) <0)
            {
            printf("Erreur a l ouverture de la socket, es tu root ???\n");
            exit(0);
            }      

      /* on veut remplir nous meme l entete IP*/
      if (setsockopt(sock,IPPROTO_IP, IP_HDRINCL, (char *)&r, sizeof(r)) ==-1 )
              {
              printf("error setsockopt\n");
      
      
            }
      /*Remplissage des entetes IP*/

      ip->ihl=5;
      ip->version=4;
      ip->tos=0;
      ip->tot_len= sizeof (struct ip) + sizeof (struct tcphdr);
      ip->id=htons(1);
      ip->frag_off=0;
      ip->ttl=255;
      ip->protocol=IPPROTO_TCP;
      ip->check=0;      /*on met 0 avt de calculer le checksum une fois que le packet sera complet*/
      ip->saddr= inet_addr("10.2.150.5"); /* adresse source , si aucune, le systeme remplis tout seul*/
      ip->daddr= destination.sin_addr.s_addr;
      
      pseudo.saddr= ip->saddr;
      pseudo.daddr= ip->daddr;
      pseudo.useless=0;
      pseudo.protocol = ip->protocol;
      pseudo.length = htons(sizeof(struct tcphdr));
      
      
      /*remplissage de l entete TCP */
      tcp->source = htons(6666);
      tcp->dest = htons(portdest);
      tcp->seq= htons(31337);
      tcp->ack_seq = htons(0);
      tcp->res1 = 0;                  
      tcp->doff = 5;
      tcp->res2 = 0;                  
      tcp->fin = 0;
      tcp->syn= 1;            /* on envoie le flag SYN*/
      tcp->rst = 0;
      tcp->psh = 0;
      tcp->ack = 0;
      tcp->urg = 0;      
      tcp->window = htons(3072);
      tcp->urg_ptr = htons(0);
      tcp->check = in_checksum((u_short *)&pseudo, sizeof(struct tcphdr) + sizeof(struct pseudohdr));
      
      ip->check = in_checksum ((u_short *)ip, sizeof(struct iphdr));

      sendto(sock,paquet, sizeof(struct iphdr) + sizeof(struct tcphdr), 0, (struct sockaddr *)&destination, sizeof(struct sockaddr));
      
      FD_ZERO(&fdsr);
      FD_SET(sock, &fdsr);

      /*timeout sur la fonction select*/
      tv_timeout.tv_sec=2;
      tv_timeout.tv_usec=0;
            
      retval = select (sock+1, &fdsr, NULL, NULL, &tv_timeout);
      
      if (FD_ISSET(sock, &fdsr))
            {
            nbr=recvfrom(sock, recev_buffer,(sizeof(struct iphdr) + sizeof(struct tcphdr)) , 0, (struct sockaddr *)&from, &from_len);
                iprecu = (struct iphdr *)recev_buffer;
                tcprecu = (struct tcphdr *) (recev_buffer + sizeof (struct iphdr));      
            
            if ( tcprecu->syn == 1 && tcprecu->ack == 1)
                  {
                  printf("%d ouvert\t",portdest);
                  }

            else if ( tcprecu->rst == 1)
                  {
                  printf("%d ferme\t",portdest);
                  }

            
      
            /*printf("Reponse de : %s\n", inet_ntoa(*((struct in_addr *)&iprecu->saddr)));
            printf("Valeur de SYN recu : %d\n", tcprecu->syn);
            printf("Valeur de ACK recu : %d\n", tcprecu->ack);
            printf("Valeur de RESET recu : %d\n\n", tcprecu->rst);*/
            
            }

      else  /*si pas de reponse....*/
            {
            printf("service firewalled : %d\n", portdest);
            }
      
close(sock);
free(paquet);
free(recev_buffer);

      
}

############


sorry for my poor english and thanks if someone can spend his time to help me


bye !!

philuxe
ASKER CERTIFIED SOLUTION
Avatar of qwyjebo
qwyjebo

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
No comment has been added lately, so it's time to clean up this TA.
I will leave the following recommendation for this question in the Cleanup topic area:

Accept: qwyjebo {http:#8190710}

Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

jmcg
EE Cleanup Volunteer