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 */
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 */
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 */
*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++;
{
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);
{
//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);