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
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-ipfw
To unsubscribe, send any mail to "[email protected]"

Reply via email to