Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 9 Mar 2011 15:36:53 +0100 (CET)
From:      "f.invernizzi@libero.it" <f.invernizzi@libero.it>
To:        freebsd-ipfw@freebsd.org
Subject:   Generating a packet from IPvw
Message-ID:  <9582756.65231299681413563.JavaMail.root@wmail21>

next in thread | raw e-mail | index | archive | help
Hi all

i am trying to do something quite odd with the IPfw (FreeSD 8.1@AMD64) for a 
particular system i am trying to build.
The idea is that whenever a dynamic rule is UNLINKED from the IPfw linked 
list, i want a fake packet to be generated and sent by the firewall.
In a quite simple configuration I had sucesfully done, using ip_output to send 
a on-the-fly generated packet, and added a call to my function in the 
UNLINK_DYN_RULE macro (ip_fw_dynamic.c ).
It looks something like:

#define UNLINK_DYN_RULE(prev, head, q) {                                \    
        ipfw_dyn_rule *old_q = q;                                       \ 
        /* Fabrizio     */                                              \
        ipfw_send_sv_pkt(q);                                    \
       

where  ipfw_send_sv_pkt(q) is 


ipfw_send_sv_pkt(struct _ipfw_dyn_rule *rule)
{
#ifndef __FreeBSD__
	return ;
#else
	struct mbuf *m;
	int len;
	struct ip *h = NULL;			
	struct tcphdr *th = NULL;
	char *payload = NULL;			/* Payload */
	char buf[DATI_SV_MAX_PAYLOAD]=""; 	/* payload */
	
	struct ipfw_flow_id *id = &(rule->id); /* Flow id  */
	
	// Payload
	sprintf(buf,"%4s%4s%12li%12li",DATI_MAGIC_STRING,DATI_SV_VERSION,rule->pcnt,
rule->bcnt);

	/* Alloca un Mbuf, non aspetta se no c'e' spazio, di tipo dati dinamici */
	MGETHDR(m, M_DONTWAIT, MT_DATA);

	if (m == NULL)
		return ;

	M_SETFIB(m, id->fib);
	
	len = sizeof(struct ip) + sizeof(struct tcphdr)  + sizeof(buf);
	// To be sure it fits in mbuf data space
	if (len > DATI_SV_MAX_PAYLOAD){
		m_freem(m);
		return;
	}

	m->m_data += max_linkhdr;
	m->m_flags |= M_SKIP_FIREWALL;
	m->m_pkthdr.len = m->m_len = len;
	m->m_pkthdr.rcvif = NULL;
	bzero(m->m_data, len);

	h = mtod(m, struct ip *);

	/* prepare for checksum */
	h->ip_p = IPPROTO_TCP;
	h->ip_ttl = 1; /* per sicurezza, nel caso per errore uscisse */
	h->ip_len = htons(sizeof(struct tcphdr));
	h->ip_src.s_addr = htonl(id->src_ip);
	//h->ip_dst.s_addr = htonl(id->dst_ip);
	struct in_addr addr;
	inet_aton("10.2.2.3", &addr);
	h->ip_dst.s_addr = addr.s_addr;

	th = (struct tcphdr *)(h + 1);
	th->th_sport = htons(id->src_port);
	th->th_dport = htons(id->dst_port);
	th->th_off = sizeof(struct tcphdr) >> 2;

	th->th_seq = htonl(0);
	th->th_ack = htonl(0);
	th->th_flags = TH_ACK; 	/* ??? */

	th->th_sum = in_cksum(m, len);

	/* finish the ip header */
	h->ip_v = 4;
	h->ip_hl = sizeof(*h) >> 2;
	h->ip_tos = IPTOS_LOWDELAY;
	h->ip_off = 0;
	/* ip_len must be in host format for ip_output */
	h->ip_len = len;
	h->ip_ttl = V_ip_defttl;
	h->ip_sum = 0;

	payload = (char *)(th + 1);
	strcpy(payload,buf);
	
	/* Invia il pacchetto */
	ip_output(m, NULL, NULL, 0, NULL, NULL); 
#endif /* __FreeBSD__ */
}

/* end of file */


As you can see it is quite bad in some assumption and a lot controls still to 
put in place, but the fact is: it does the work. I can see the packet coming 
out on the first system

Now. If i try on a system with ng_ipfw and VIMAGE enabled (working on a 
specific jailed workspace)  the code apparently does not do anything. I have 
done a lot of debugging, but with no luck.
Can someoune help me?

Thanks in advance

Fabrizio



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9582756.65231299681413563.JavaMail.root>