Thread: Problem while constructing IP packet and sending using socket() system call

  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    36

    Problem while constructing IP packet and sending using socket() system call

    Hi,

    I tried to construct an IP packet and send that using the RAW Socket, but when I tried to capture the same using packet sniffer (ethereal), it showed malformed packet.

    The RAW socket code is as follows:

    int sockraw = socket(AF_INET, SOCK_RAW, htons(ETH_P_IP));

    setsockopt(sd, SOL_SOCKET, SO_BROADCAST,(char *)&one, sizeof(one);

    setsockopt(sd, IPPROTO_IP, IP_HDRINCL,(char *)&one, sizeof(one);

    Can anyone plz let me know what exactly I need to do if I want to construct my own packet (IP/UDP/TCP) etc and send that using RAW Socket. I want to using my own values of various header fields such as TOS, TTL, Source IP Address, Destination IP Address, Source Port and Destination POrt (for UDP/TCP).

    Please guide me for the same.

    Thanks,
    Cavestine

  2. #2
    Registered User
    Join Date
    Oct 2007
    Posts
    36
    Also if any1 can let me know how exactly to use setsockopt() system call for various causes/ uses.

  3. #3
    Registered User
    Join Date
    Jun 2007
    Location
    Rome, NY
    Posts
    24
    May I recommend UNIX Network Programming (I am assuming some *nix) by Richard Stevens. It's a great book and has a whole chapter dedicated to raw sockets.

    Also, posting more of your code would be helpful.

  4. #4
    Registered User
    Join Date
    Oct 2007
    Posts
    36
    Hi,

    plz find the complete source code. I am trying to hardcode the header values for IP and UDP header and send the packets using RAW Socket.

    Code:
    /*Writing some small packet generator
     */
    
    #include <stdio.h>
    #include <sys/time.h>
    #include <netdb.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netinet/ether.h>
    #include <sys/times.h>
    #include <sys/param.h>
    #include <sys/signal.h>
    #include <netinet/ip.h>
    #include <errno.h>
    #include <netinet/udp.h>
    #include <netinet/ip_icmp.h>
    #include <features.h>    /* for the glibc version number */
    #if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
    #include <netpacket/packet.h>
    #include <net/ethernet.h>     /* the L2 protocols */
    #else
    #include <asm/types.h>
    #include <linux/if_packet.h>
    #include <linux/if_ether.h>   /* The L2 protocols */
    #endif
    
    #define DEBUG_MESG(arg...) \
                    printf(arg)
    
    struct pseudohdr
    {
            u_int32_t saddr;
            u_int32_t daddr;
            u_int8_t zero;
            u_int8_t proto;
            u_int16_t len;
    };
    
    #define PSEUDOHDR_SIZE sizeof(struct pseudohdr)
    struct sockaddr_in remote;
    struct sockaddr_in local;
    
    u_int16_t cksum(u_int16_t *buf, int nbytes)
    {
            int opt_badcksum = 0;
            u_int32_t sum;
            u_int16_t oddbyte;
    
            sum = 0;
            while (nbytes > 1) {
                    sum += *buf++;
                    nbytes -= 2;
            }
    
            if (nbytes == 1) {
                    oddbyte = 0;
                    *((u_int16_t *) &oddbyte) = *(u_int8_t *) buf;
                    sum += oddbyte;
            }
    
            sum = (sum >> 16) + (sum & 0xffff);
            sum += (sum >> 16);
    
            /* return a bad checksum with --badcksum option */
            if (opt_badcksum) sum ^= 0x5555;
    
            return (u_int16_t) ~sum;
    }
    
    char *udppacket()
    {
            local.sin_addr.s_addr = inet_addr("10.100.12.21");
            remote.sin_addr.s_addr = inet_addr("10.100.12.102");
            char *udppacket;
            struct pseudohdr *pseudohdr;
            int totalsize = sizeof(struct udphdr) + PSEUDOHDR_SIZE;
            udppacket = (char *)malloc(sizeof(struct udphdr) + PSEUDOHDR_SIZE);
            struct udphdr *udphdr;
    
            pseudohdr = (struct pseudohdr *)udppacket;
            udphdr = (struct udphdr *)(udppacket + PSEUDOHDR_SIZE);
    
            memset(udppacket, '0', totalsize);
            memcpy(&pseudohdr->saddr, &local.sin_addr.s_addr, 4);
            memcpy(&pseudohdr->daddr, &remote.sin_addr.s_addr, 4);
            pseudohdr->proto = 17;
            pseudohdr->len = htons(totalsize - PSEUDOHDR_SIZE);
            memset(&(pseudohdr->zero), '0', sizeof(pseudohdr->zero));
    
            udphdr->source = htons(1000);
            udphdr->dest = htons(1200);
            udphdr->len = sizeof(struct udphdr);
            udphdr->check = cksum((u_int16_t *)udppacket, totalsize);
            return (udppacket + PSEUDOHDR_SIZE);
    }
    
    void socket_broadcast(int sd)
    {
            const int one = 1;
    
            if (setsockopt(sd, SOL_SOCKET, SO_BROADCAST,(char *)&one, sizeof(one)) == -1)
            {
                    printf("[socket_broadcast] can't set SO_BROADCAST option\n");
                    /* non fatal error */
            }
    }
    
    void socket_iphdrincl(int sd)
    {
            const int one = 1;
    
            if (setsockopt(sd, IPPROTO_IP, IP_HDRINCL,(char *)&one, sizeof(one)) == -1)
            {
                    printf("[socket_broadcast] can't set IP_HDRINCL option\n");
                    /* non fatal error */
            }
    }
    
    void SendPacket(char *buffer)
    {
            struct sockaddr_in src_addr;
            struct sockaddr_in dest_addr;
    
           int sockraw = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
            
            const int one = 1;
    
            socket_broadcast(sockraw);
            /* set SO_IPHDRINCL option */
            socket_iphdrincl(sockraw);
    
            src_addr.sin_family = AF_INET;
            src_addr.sin_addr.s_addr = inet_addr("10.100.12.21");
            src_addr.sin_port = htons(9095);
            memset(&src_addr.sin_zero, '\0', 8);
    
            dest_addr.sin_family = AF_INET;
            dest_addr.sin_addr.s_addr = inet_addr("10.100.12.102");
            dest_addr.sin_port = htons(9095);
            memset(&dest_addr.sin_zero, '\0', 8);
       
           if(bind(sockraw, (struct sockaddr *)&src_addr, sizeof(struct sockaddr)) == -1)
            {
                    perror("bind");
            }
    
            if(sendto(sockraw, buffer, sizeof(buffer), 0, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr)) == -1)
            {
                    perror("sendto");
            }
    
    int main()
    {
            char *packet;
       
            int packetsize = sizeof(struct iphdr) + sizeof(struct udphdr);
            packet = (char *)malloc(packetsize + sizeof(struct udphdr));
            struct iphdr *iphdr;
            memset(packet, 0, packetsize);
            iphdr = (struct iphdr *)packet;
            struct sockaddr_in src_addr, dest_addr;
            src_addr.sin_addr.s_addr = inet_addr("10.100.12.21");
            dest_addr.sin_addr.s_addr = inet_addr("10.100.12.102");
    
            char *src, *dest;
            src = (char *)&src_addr.sin_addr;
            dest = (char *)&dest_addr.sin_addr;
    
            iphdr->version = 4;
            iphdr->tos = 10;
            iphdr->id = htons(100);
            iphdr->frag_off = 0;
            iphdr->ttl = 120;
            iphdr->protocol = 17;
            iphdr->check = 0;
            iphdr->tot_len = htons(packetsize);
            iphdr->ihl = htons((sizeof(struct iphdr) + 3) >> 2);
    
            memcpy(&iphdr->saddr, src, sizeof(iphdr->saddr));
            memcpy(&iphdr->daddr, dest, sizeof(iphdr->daddr));
    
            data = (char *)malloc(sizeof(struct udphdr));
            data = udppacket();
            memcpy((packet + sizeof(struct iphdr)), data, sizeof(struct udphdr));
           
            int i;
    
            for(i = 1; i <= 10; i++)
            {
                    SendPacket(packet);
    
            }
    
            return 0;
    }
    plz let me know the changes required...

  5. #5
    Registered User
    Join Date
    Oct 2007
    Posts
    36
    can any1 help me in this issue and suggest me the way to fix it...

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by cavestine View Post
    can any1 help me in this issue and suggest me the way to fix it...
    Repeated questions aren't going to get you the answer any faster.

    The answer is to stop using raw sockets and use an actual UDP socket, if that's what you are sending. Why waste time comprehending a bunch of unnecessary crap.

    As for setsockopt(), a manual would be far more helpful than me randomly guessing which calls you are interested in.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    man setsockopt.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User
    Join Date
    Oct 2007
    Posts
    36
    thanx 4 ur suggestion...BUT still thats NOT working

  9. #9
    Registered User Tommo's Avatar
    Join Date
    Jun 2007
    Location
    Scotland
    Posts
    101
    http://security-freak.net/raw-sockets/raw-sockets.html
    http://packetstormsecurity.nl/progra...raw_socket.txt

    May I recommend UNIX Network Programming (I am assuming some *nix) by Richard Stevens. It's a great book and has a whole chapter dedicated to raw sockets.
    Yes, even though I havn't read it, it is regarded as the best book on the subject (not just raw sockets). After all, it appeared in Wayne's World 2:
    Quote Originally Posted by Garth Algar
    That's a UNIX book
    Last edited by Tommo; 10-15-2007 at 05:21 AM.

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > data = (char *)malloc(sizeof(struct udphdr));
    > data = udppacket();
    What happens to the memory you allocated.

    > return (udppacket + PSEUDOHDR_SIZE);
    Why are you returning a pointer to somewhere inside the buffer, and not the start.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #11
    Registered User
    Join Date
    Oct 2007
    Posts
    36

    Thumbs up

    hey Tommo, thanx a lot for the links...those are really very clear...I appreciate ur effort...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. unable to recieve UDP packet
    By caroundw5h in forum Networking/Device Communication
    Replies: 15
    Last Post: 09-19-2007, 11:11 AM
  2. Winsock packet problem
    By Rare177 in forum Windows Programming
    Replies: 7
    Last Post: 10-05-2004, 04:53 PM
  3. problem with connecting to my own machine
    By EvBladeRunnervE in forum Networking/Device Communication
    Replies: 10
    Last Post: 07-24-2003, 04:16 PM