5 * Grzegorz Borowiak <grzes@gnu.univ.gda.pl>
6 * Bart De Schuymer <bdschuym@pandora.be>
11 #include <linux/if_arp.h>
13 #include <linux/module.h>
14 #include <linux/netfilter/x_tables.h>
15 #include <linux/netfilter_bridge/ebtables.h>
16 #include <linux/netfilter_bridge/ebt_arpreply.h>
19 ebt_arpreply_tg(struct sk_buff
*skb
, const struct xt_action_param
*par
)
21 const struct ebt_arpreply_info
*info
= par
->targinfo
;
22 const __be32
*siptr
, *diptr
;
24 const struct arphdr
*ap
;
26 const unsigned char *shp
;
27 unsigned char _sha
[ETH_ALEN
];
29 ap
= skb_header_pointer(skb
, 0, sizeof(_ah
), &_ah
);
33 if (ap
->ar_op
!= htons(ARPOP_REQUEST
) ||
34 ap
->ar_hln
!= ETH_ALEN
||
35 ap
->ar_pro
!= htons(ETH_P_IP
) ||
39 shp
= skb_header_pointer(skb
, sizeof(_ah
), ETH_ALEN
, &_sha
);
43 siptr
= skb_header_pointer(skb
, sizeof(_ah
) + ETH_ALEN
,
48 diptr
= skb_header_pointer(skb
,
49 sizeof(_ah
) + 2 * ETH_ALEN
+ sizeof(_sip
),
54 arp_send(ARPOP_REPLY
, ETH_P_ARP
, *siptr
, (struct net_device
*)par
->in
,
55 *diptr
, shp
, info
->mac
, shp
);
60 static int ebt_arpreply_tg_check(const struct xt_tgchk_param
*par
)
62 const struct ebt_arpreply_info
*info
= par
->targinfo
;
63 const struct ebt_entry
*e
= par
->entryinfo
;
65 if (BASE_CHAIN
&& info
->target
== EBT_RETURN
)
67 if (e
->ethproto
!= htons(ETH_P_ARP
) ||
68 e
->invflags
& EBT_IPROTO
)
73 static struct xt_target ebt_arpreply_tg_reg __read_mostly
= {
76 .family
= NFPROTO_BRIDGE
,
78 .hooks
= (1 << NF_BR_NUMHOOKS
) | (1 << NF_BR_PRE_ROUTING
),
79 .target
= ebt_arpreply_tg
,
80 .checkentry
= ebt_arpreply_tg_check
,
81 .targetsize
= sizeof(struct ebt_arpreply_info
),
85 static int __init
ebt_arpreply_init(void)
87 return xt_register_target(&ebt_arpreply_tg_reg
);
90 static void __exit
ebt_arpreply_fini(void)
92 xt_unregister_target(&ebt_arpreply_tg_reg
);
95 module_init(ebt_arpreply_init
);
96 module_exit(ebt_arpreply_fini
);
97 MODULE_DESCRIPTION("Ebtables: ARP reply target");
98 MODULE_LICENSE("GPL");