Find the answer to your Linux question:
Results 1 to 2 of 2
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1

    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 how to construct my own IP/UDP/TCP Packet with headers and options.

    Thanks,
    Cavestine


    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;
    }

  2. #2
    Linux Engineer wje_lf's Avatar
    Join Date
    Sep 2007
    Location
    Mariposa
    Posts
    1,192
    Go here.

    Just be sure you use your power for good and not for evil. Raw sockets can be used for IP spoofing and denial of service attacks. Don't do this.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •