sending packet is not working - Building firewall/proxyserver using libpcap

sending packet is not working - Building firewall/proxyserver using libpcap

Post by Vija » Mon, 27 Jan 2003 01:29:38



Hello friends,

I am working on developing a firewall.

The design is like disable access to Internet on specific port. For that my
code is working like this...

I am sending req.(http://www.google.com / 216.239.51.101) in IE from one of
my inner LAN's machine (172.16.2.2)  ----->  eth1(172.16.2.1) on linux
server.
On linux server - It captures all packets coming on the gateway from
internal network (eth1) card using libpcap.
And then i am sending only selected data coming from inner network to
eth0 --- which is my real gateway to internet.

So i guess that i will get the html page from www.google.com on eth0 as a
bunch of packets.

To test it - I have created another small program which reads all incoming
traffic on eth0. But i am not getting the my expected packets .

Can you help me or give me a direction to work on ? I am also having a bit
knowledge about TCP/IP. I still believe that the packet that i am sending
(on eth0) is not tranmitting the same message that i have received (on
eth1).

Thank you in advance.

Vijay.

Here is the main firewall program.

#define _BSD_SOURCE 1

#include <stdio.h>
#include <pcap.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/if_ether.h>
#include <netinet/tcp.h>

#include <string.h>

/* Ethernet header */
struct sniff_ethernet {
   u_char  ether_dhost[ETHER_ADDR_LEN];    /* Destination host address */
   u_char  ether_shost[ETHER_ADDR_LEN];    /* Source host address */
   u_short ether_type;                     /* IP? ARP? RARP? etc */

};

/* IP header */
struct sniff_ip {
   #if BYTE_ORDER == LITTLE_ENDIAN
      u_int ip_hl:4,        /* header length */
            ip_v:4;         /* version */
   #if BYTE_ORDER == BIG_ENDIAN
      u_int ip_v:4,         /* version */
            ip_hl:4;        /* header length */
   #endif
   #endif /* not _IP_VHL */
   u_char  ip_tos;                 /* type of service */
   u_short ip_len;                 /* total length */
   u_short ip_id;                  /* identification */
   u_short ip_off;                 /* fragment offset field */
   #define IP_RF 0x8000            /* reserved fragment flag */
   #define IP_DF 0x4000            /* dont fragment flag */
   #define IP_MF 0x2000            /* more fragments flag */
   #define IP_OFFMASK 0x1fff       /* mask for fragmenting bits */
   u_char  ip_ttl;                 /* time to live */
   u_char  ip_p;                   /* protocol */
   u_short ip_sum;                 /* checksum */
   struct  in_addr ip_src,ip_dst;  /* source and dest address */

};

/* TCP header */
struct sniff_tcp {
   u_short th_sport;                       /* source port */
   u_short th_dport;                       /* destination port */
   tcp_seq th_seq;                         /* sequence number */
   tcp_seq th_ack;                         /* acknowledgement number */
   #if BYTE_ORDER == LITTLE_ENDIAN
      u_int th_x2:4,                /* (unused) */
            th_off:4;               /* data offset */
   #endif
   #if BYTE_ORDER == BIG_ENDIAN
      u_int th_off:4,               /* data offset */
            th_x2:4;                /* (unused) */
   #endif
   u_char  th_flags;
   #define TH_FIN  0x01
   #define TH_SYN  0x02
   #define TH_RST  0x04
   #define TH_PUSH 0x08
   #define TH_ACK  0x10
   #define TH_URG  0x20
   #define TH_ECE  0x40
   #define TH_CWR  0x80
   #define TH_FLAGS
(TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
   u_short th_win;                         /* window */
   u_short th_sum;                         /* checksum */
   u_short th_urp;                         /* urgent pointer */

};

void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char
*packet);
void send_packet(char *,int,char[16],u_int16_t);

void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char
*packet) {
   static int count = 1;                   /* Just a counter of how many
packets we've had */
   /* Define pointers for packet's attributes */
   const struct sniff_ethernet *ethernet;  /* The ethernet header */
   const struct sniff_ip *ip;              /* The IP header */
   const struct sniff_tcp *tcp;            /* The TCP header */
   const char *payload;                    /* Packet payload */
   /* And define the size of the structures we're using */
   int size_ethernet = sizeof(struct sniff_ethernet);
   int size_ip = sizeof(struct sniff_ip);
   int size_tcp = sizeof(struct sniff_tcp);

   char *ptr_src1,*ptr_dest1,*ptr_buffer,*ptr1;
   u_int16_t src_port1,dest_port1;

   u_int16_t size_ip_pack;
   char *start_ip_pack;
   char test_dest1[] = "216.239.51.101";

   /* -- Define our packet's attributes -- */
   ethernet = (struct sniff_ethernet*)(packet);
   ip = (struct sniff_ip*)(packet + size_ethernet);
   tcp = (struct sniff_tcp*)(packet + size_ethernet + size_ip);
   payload = (u_char *)(packet + size_ethernet + size_ip + size_tcp);

   if(ip->ip_p == IPPROTO_TCP) {
      ptr_buffer = inet_ntoa(ip->ip_src);
      ptr_src1 = (char *) malloc(strlen(ptr_buffer)+1);
      strcpy(ptr_src1,ptr_buffer);
      src_port1 = ntohs(tcp->th_sport);

      ptr_buffer = inet_ntoa(ip->ip_dst);
      ptr_dest1 = (char *) malloc(strlen(ptr_buffer)+1);
      strcpy(ptr_dest1,ptr_buffer);
      dest_port1 = ntohs(tcp->th_dport);

      if((strcmp(ptr_src1,"172.16.2.2") ==0) || (strcmp(ptr_src1,test_dest1)
==0)) {
         if((strcmp(ptr_dest1,"172.16.2.2") ==0) ||
(strcmp(ptr_dest1,test_dest1) ==0)) {
            printf("Packet No : %d, From : %s:%d\t To: %s:%d\n", count,
ptr_src1, src_port1, ptr_dest1, dest_port1);
            //printf("Payload: %s\n\n", payload);
            //puts(payload);

            size_ip_pack = ntohs(ip->ip_len);
            start_ip_pack = (char *)malloc(size_ip_pack);
            memcpy(start_ip_pack,packet + size_ethernet,size_ip_pack);

            send_packet(start_ip_pack,size_ip_pack,ptr_dest1,dest_port1);
            free(start_ip_pack);
         }
      }

      free(ptr_src1);
      free(ptr_dest1);
   }
   count++;

}

void send_packet(char *start,int size,char *d_addr,u_int16_t d_port)
{
       struct sockaddr_in address;
       int sockfd;
       int on = 1;

       if((sockfd = socket(AF_INET,SOCK_RAW,IPPROTO_RAW)) < 0)
       {
               perror("Socket creation");
       }
       if((setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,&on,sizeof(int))) < 0)
       {
               perror("setsockopt");
       }

       memset(&address,'\0',sizeof(address));

       address.sin_family = AF_INET;
       address.sin_port = htons(d_port);
       address.sin_addr.s_addr = inet_addr(d_addr);

       if(sendto(sockfd,start,size,0,(struct sockaddr
*)&address,sizeof(struct sockaddr))<0)
       {
               perror("send");
       }
       //else printf("packet sent\n");

       free(start);
       close(sockfd);

}

int main()
{
 //char *dev;
   char dev[] = "eth1";
   bpf_u_int32 mask;
   bpf_u_int32 net;

   char errbuf[PCAP_ERRBUF_SIZE];

   pcap_t *handle;
   struct pcap_pkthdr header;
   const u_char *packet;

   struct bpf_program filter;
   char filter_app[] = "";

   int datalink;        /* Type of datalink SLIP/PPP/Ethernet */

   //dev = pcap_lookupdev(errbuf);
 //printf("Device : %s\n", dev);

   pcap_lookupnet(dev,&net,&mask,errbuf);

   if((handle = pcap_open_live(dev, BUFSIZ, 0, 0, errbuf))== NULL) {
      printf("Error opening device: %s", errbuf);
   }

   if((datalink = pcap_datalink(handle)) < 0 ) {
      printf("Datalink error : %s", pcap_geterr(handle));
   }
   //printf("Datalink = %d\n", datalink);

   if( pcap_compile(handle, &filter, filter_app, 0, net) == -1) {
      printf("pcap_compile borqed\n");
      exit(1);
   }
   if (pcap_setfilter(handle, &filter) == -1) {
      printf("pcap_setfilter said 'eat shit'\n");
      exit(1);
   }

   //pcap_loop(handle, -1, got_packet, NULL);
   while(1) {
      while((packet = (char *) pcap_next(handle, &header)) == NULL);
      got_packet("", &header,packet);
   }

   pcap_close(handle);
 return(0);

}

 
 
 

sending packet is not working - Building firewall/proxyserver using libpcap

Post by DevLocu » Mon, 27 Jan 2003 06:21:07


On Sat, 25 Jan 2003 08:29:38 +0000, Vijay wrote:
> Hello friends,

> I am working on developing a firewall.

> The design is like disable access to Internet on specific port. For that my
> code is working like this...

> I am sending req.(http://www.google.com / 216.239.51.101) in IE from one of
> my inner LAN's machine (172.16.2.2)  ----->  eth1(172.16.2.1) on linux
> server.
> On linux server - It captures all packets coming on the gateway from
> internal network (eth1) card using libpcap.
> And then i am sending only selected data coming from inner network to
> eth0 --- which is my real gateway to internet.

> So i guess that i will get the html page from www.google.com on eth0 as a
> bunch of packets.

> To test it - I have created another small program which reads all incoming
> traffic on eth0. But i am not getting the my expected packets .

> Can you help me or give me a direction to work on ? I am also having a bit
> knowledge about TCP/IP. I still believe that the packet that i am sending
> (on eth0) is not tranmitting the same message that i have received (on
> eth1).

> Thank you in advance.

> Vijay.

> Here is the main firewall program.

> #define _BSD_SOURCE 1

> #include <stdio.h>
> #include <pcap.h>
> #include <stdlib.h>
> #include <errno.h>
> #include <sys/socket.h>
> #include <netinet/in.h>
> #include <arpa/inet.h>
> #include <net/if.h>
> #include <netinet/if_ether.h>
> #include <netinet/tcp.h>

> #include <string.h>

> /* Ethernet header */
> struct sniff_ethernet {
>    u_char  ether_dhost[ETHER_ADDR_LEN];    /* Destination host address */
>    u_char  ether_shost[ETHER_ADDR_LEN];    /* Source host address */
>    u_short ether_type;                     /* IP? ARP? RARP? etc */
> };

> /* IP header */
> struct sniff_ip {
>    #if BYTE_ORDER == LITTLE_ENDIAN
>       u_int ip_hl:4,        /* header length */
>             ip_v:4;         /* version */
>    #if BYTE_ORDER == BIG_ENDIAN
>       u_int ip_v:4,         /* version */
>             ip_hl:4;        /* header length */
>    #endif
>    #endif /* not _IP_VHL */
>    u_char  ip_tos;                 /* type of service */
>    u_short ip_len;                 /* total length */
>    u_short ip_id;                  /* identification */
>    u_short ip_off;                 /* fragment offset field */
>    #define IP_RF 0x8000            /* reserved fragment flag */
>    #define IP_DF 0x4000            /* dont fragment flag */
>    #define IP_MF 0x2000            /* more fragments flag */
>    #define IP_OFFMASK 0x1fff       /* mask for fragmenting bits */
>    u_char  ip_ttl;                 /* time to live */
>    u_char  ip_p;                   /* protocol */
>    u_short ip_sum;                 /* checksum */
>    struct  in_addr ip_src,ip_dst;  /* source and dest address */
> };

> /* TCP header */
> struct sniff_tcp {
>    u_short th_sport;                       /* source port */
>    u_short th_dport;                       /* destination port */
>    tcp_seq th_seq;                         /* sequence number */
>    tcp_seq th_ack;                         /* acknowledgement number */
>    #if BYTE_ORDER == LITTLE_ENDIAN
>       u_int th_x2:4,                /* (unused) */
>             th_off:4;               /* data offset */
>    #endif
>    #if BYTE_ORDER == BIG_ENDIAN
>       u_int th_off:4,               /* data offset */
>             th_x2:4;                /* (unused) */
>    #endif
>    u_char  th_flags;
>    #define TH_FIN  0x01
>    #define TH_SYN  0x02
>    #define TH_RST  0x04
>    #define TH_PUSH 0x08
>    #define TH_ACK  0x10
>    #define TH_URG  0x20
>    #define TH_ECE  0x40
>    #define TH_CWR  0x80
>    #define TH_FLAGS
> (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
>    u_short th_win;                         /* window */
>    u_short th_sum;                         /* checksum */
>    u_short th_urp;                         /* urgent pointer */
> };

> void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char
> *packet);
> void send_packet(char *,int,char[16],u_int16_t);

> void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char
> *packet) {
>    static int count = 1;                   /* Just a counter of how many
> packets we've had */
>    /* Define pointers for packet's attributes */
>    const struct sniff_ethernet *ethernet;  /* The ethernet header */
>    const struct sniff_ip *ip;              /* The IP header */
>    const struct sniff_tcp *tcp;            /* The TCP header */
>    const char *payload;                    /* Packet payload */
>    /* And define the size of the structures we're using */
>    int size_ethernet = sizeof(struct sniff_ethernet);
>    int size_ip = sizeof(struct sniff_ip);
>    int size_tcp = sizeof(struct sniff_tcp);

>    char *ptr_src1,*ptr_dest1,*ptr_buffer,*ptr1;
>    u_int16_t src_port1,dest_port1;

>    u_int16_t size_ip_pack;
>    char *start_ip_pack;
>    char test_dest1[] = "216.239.51.101";

>    /* -- Define our packet's attributes -- */
>    ethernet = (struct sniff_ethernet*)(packet);
>    ip = (struct sniff_ip*)(packet + size_ethernet);
>    tcp = (struct sniff_tcp*)(packet + size_ethernet + size_ip);
>    payload = (u_char *)(packet + size_ethernet + size_ip + size_tcp);

>    if(ip->ip_p == IPPROTO_TCP) {
>       ptr_buffer = inet_ntoa(ip->ip_src);
>       ptr_src1 = (char *) malloc(strlen(ptr_buffer)+1);
>       strcpy(ptr_src1,ptr_buffer);
>       src_port1 = ntohs(tcp->th_sport);

>       ptr_buffer = inet_ntoa(ip->ip_dst);
>       ptr_dest1 = (char *) malloc(strlen(ptr_buffer)+1);
>       strcpy(ptr_dest1,ptr_buffer);
>       dest_port1 = ntohs(tcp->th_dport);

>       if((strcmp(ptr_src1,"172.16.2.2") ==0) || (strcmp(ptr_src1,test_dest1)
> ==0)) {
>          if((strcmp(ptr_dest1,"172.16.2.2") ==0) ||
> (strcmp(ptr_dest1,test_dest1) ==0)) {
>             printf("Packet No : %d, From : %s:%d\t To: %s:%d\n", count,
> ptr_src1, src_port1, ptr_dest1, dest_port1);
>             //printf("Payload: %s\n\n", payload);
>             //puts(payload);

>             size_ip_pack = ntohs(ip->ip_len);
>             start_ip_pack = (char *)malloc(size_ip_pack);
>             memcpy(start_ip_pack,packet + size_ethernet,size_ip_pack);

>             send_packet(start_ip_pack,size_ip_pack,ptr_dest1,dest_port1);
>             free(start_ip_pack);
>          }
>       }

>       free(ptr_src1);
>       free(ptr_dest1);
>    }
>    count++;
> }

> void send_packet(char *start,int size,char *d_addr,u_int16_t d_port)
> {
>        struct sockaddr_in address;
>        int sockfd;
>        int on = 1;

>        if((sockfd = socket(AF_INET,SOCK_RAW,IPPROTO_RAW)) < 0)
>        {
>                perror("Socket creation");
>        }
>        if((setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,&on,sizeof(int))) < 0)
>        {
>                perror("setsockopt");
>        }

>        memset(&address,'\0',sizeof(address));

>        address.sin_family = AF_INET;
>        address.sin_port = htons(d_port);
>        address.sin_addr.s_addr = inet_addr(d_addr);

>        if(sendto(sockfd,start,size,0,(struct sockaddr
> *)&address,sizeof(struct sockaddr))<0)
>        {
>                perror("send");
>        }
>        //else printf("packet sent\n");

>        free(start);
>        close(sockfd);
> }

> int main()
> {
>  //char *dev;
>    char dev[] = "eth1";
>    bpf_u_int32 mask;
>    bpf_u_int32 net;

>    char errbuf[PCAP_ERRBUF_SIZE];

>    pcap_t *handle;
>    struct pcap_pkthdr header;
>    const u_char *packet;

>    struct bpf_program filter;
>    char filter_app[] = "";

>    int datalink;        /* Type of datalink SLIP/PPP/Ethernet */

>    //dev = pcap_lookupdev(errbuf);
>  //printf("Device : %s\n", dev);

>    pcap_lookupnet(dev,&net,&mask,errbuf);

>    if((handle = pcap_open_live(dev, BUFSIZ, 0, 0, errbuf))== NULL) {
>       printf("Error opening device: %s", errbuf);
>    }

>    if((datalink = pcap_datalink(handle)) < 0 ) {
>       printf("Datalink error : %s", pcap_geterr(handle));
>    }
>    //printf("Datalink = %d\n", datalink);

>    if( pcap_compile(handle, &filter, filter_app, 0, net) == -1) {
>       printf("pcap_compile borqed\n");
>       exit(1);
>    }
>    if (pcap_setfilter(handle, &filter) == -1) {
>       printf("pcap_setfilter said 'eat shit'\n");
>       exit(1);
>    }

>    //pcap_loop(handle, -1, got_packet, NULL);
>    while(1) {
>       while((packet = (char *) pcap_next(handle, &header)) == NULL);
>       got_packet("", &header,packet);
>    }

>    pcap_close(handle);
>  return(0);
> }

You need to get the IP address of eth0 and set the packet's source ip to
that so the server you are sending it to knows where to send a reply,
otherwise some other computer on the internet is recieving your packets
...

- DevLocus