Wondering why this queue handler doesn't work
Jared Redgrift Burdin
jburdin@mitre.org
Mon, 24 Jul 2000 05:58:40 -0500
I am using this queue handler to do a PREROUTING direct mapping of a
destination ip address.
For example, changing an ip address 129.83.46.7 to 1.1.1.7. I've tried
prerouting rules in both the nat and mangle tables, with the destination
address as the filter rule and QUEUE as the target. Neither appears to
work.
I'm using my machine as a router and am trying to ping from one machine
on one side of the router to another machine on the other side of the
router. My debugging output suggest it's working, but my tcpdump stuff
tells me nothing's working. I.E. I run tcpdump on the two pertinent
interfaces, the input interface reports the unedited destination
address, the output interface reports absolutely nothing.
Here's a copy of my code
Thanks for any help you can offer.
Sincerely,
Jared Burdin
/*
* ipqmdnat.c by Jared Burdin <jburdin@mitre.org>
* version 1.0
*
*
* Based on ipqdemo.c by Alexander Demenshin
*
*
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4/ip_queue.h>
#include <linux/ip.h>
#include "include/libipq/libipq.h"
/* Normally, we should not expect that packets will be so big,
even including metadata, but who knows? :)
*/
#define MAX_PACKET_LEN 8192
int main(int argc, char **argv)
{
struct ipq_handle *qh;
struct ipq_packet_msg *qpkt;
struct iphdr *iph;
unsigned char buff[sizeof *qpkt + MAX_PACKET_LEN];
int type;
int len;
FILE *fp;
char ralph[256];
int a=0;
int i, j;
uint32_t binarynm=0;
uint32_t base;
uint32_t odaddr;
int count=0;
base = ntohl((1<<8)|(1<<16)|(1<<24));
fprintf(stderr, "Base is: %s\n", inet_ntoa(base));
fp = fopen("/sbin/ANT.conf", "r"); /* Relevant information in this file
*/
while((fgetc(fp)) != 10)
fseek(fp, 0, SEEK_CUR); /* The value of the newline character is 10
*/
fgets(ralph, 256, fp); /* Grab netmask on second line of ANT.conf */
for(i=0;(int)ralph[i]!=0;i++){ /* Now put it into an int. */
a*=10;
a+=(int)ralph[i]-48;
}
fclose(fp);
for(j = a; j>0; j--) /* Convert that int into a netmask. */
binarynm|=(1<<(32-j));
binarynm = ntohl(binarynm);
/* Init first (flags are not implemented; yet) */
if ( (qh = ipq_create_handle(0)) == NULL) {
/* Run away... */
ipq_perror("create_handle()");
exit(1);
}
/* We would like to receive not only metadata... */
if (ipq_set_mode(qh, IPQ_COPY_PACKET, MAX_PACKET_LEN) < 0) {
ipq_perror("set_mode()");
goto cleanup;
}
/*
* Now real fun begins... Just stay in loop, read packets,
* accept them if they are IP.
*/
while(1) {
len = ipq_read(qh, buff, sizeof buff, 0);
if (len == 0) {
fprintf(stderr, "read(): Zero length packet; ingnoring\n");
continue;
}
if (len < 0) {
ipq_perror("read()");
goto cleanup;
}
qpkt = ipq_get_packet(buff);
iph = (struct iphdr *)qpkt->payload;
/* If packet type from kernel is not known to us,
* just ignore it (but notify user)
*/
if ((type = ipq_message_type(buff)) != IPQM_PACKET) {
fprintf(stderr, "read(): Unknown message type %u\n",
type);
continue;
}
/* Packet destination address is mangled here */
odaddr = (iph->daddr);
//fprintf(stderr, "Netmask is: %s\n", inet_ntoa(binarynm));
count++;
fprintf(stderr, "Packet # %d\n", count);
fprintf(stderr, "Original ip address: %s\n", inet_ntoa(odaddr));
odaddr &= ~binarynm; /*mask out the stuff we don't want.*/
base &= binarynm; /*mask out the stuff we don't want.*/
/* Rewrite IP header */
iph->daddr = odaddr | base;
//fprintf(stderr, "Modified ip address: %s\n",
inet_ntoa(iph->daddr));
/* Just accept, nothing more... */
/* Originally 0 NULL*/
if (ipq_set_verdict(qh, qpkt->packet_id, NF_ACCEPT, sizeof(buff),
buff) < 0) {
ipq_perror("set_verdict(): Oops!");
goto cleanup;
}
//fprintf(stderr, "Modified ip address: %s\n", inet_ntoa(((struct
iphdr *)qpkt->payload)->daddr));
fprintf(stderr, "Modified ip address: %s\n", inet_ntoa(((struct iphdr
*)ipq_get_packet(buff)->payload)->daddr));
}
cleanup:
ipq_destroy_handle(qh);
}
And the contents of ANT.conf are
1.2.3.4
24