Re: ebt_ppp extension module for ebtables

Bart De Schuymer <[email protected]> Thu, 03 Jun 2010 18:35:23 +0200
Newsgroups gmane.linux.network.bridge.ebtables.devel
Message-ID <[email protected]>
Hi,

you seem to be missing the kernel part for your module.

cheers,
Bart

Eric delalandes schreef:
> Hello to all,
>
> I have written an extension in order to filter pppoe and ppp frames. So extension names are ebt_ppp.c and ebt_ppp.h. The goal of these extension is to filter specific PPP discovery packet like PADO or PADS and specific PPP session packet on  PPPOE protocol and PPP layer.  I have used ebt_vlan.c and ebt_vlan.h as template. See description as below:
>
> /* ebt_ppp
>  * 
>  * Authors:
>  * Bart De Schuymer <[email protected]>
>  * Nick Fedchik <nick-UvdXiu2sajOKBXSJ/[email protected]> 
>  * 
>  * June, 2002
>  */
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <getopt.h>
> #include <ctype.h>
> #include "../include/ebtables_u.h"
> #include "../include/ethernetdb.h"
> #include <linux/netfilter_bridge/ebt_ppp.h>
> #include <linux/if_ether.h>
>
> #define NAME_PPP_CODE    "code"
> #define NAME_PPP_LENGTH  "length"
> #define NAME_PPP_PPPTYPE "ppptype"
>
> #define PPP_CODE    '1'
> #define PPP_LENGTH  '2'
> #define PPP_PPPTYPE '3'
>
> static struct option opts[] = {
>     {"ppp-code"   , required_argument, NULL, PPP_CODE},
>     {"ppp-length" , required_argument, NULL, PPP_LENGTH},
>     {"ppp-ppptype", required_argument, NULL, PPP_PPPTYPE},
>     { 0 }
> };
>
> /*
>  * option inverse flags definition 
>  */
> #define OPT_PPP_CODE     0x01
> #define OPT_PPP_LENGTH   0x02
> #define OPT_PPP_PPPTYPE  0x04
> #define OPT_PPP_FLAGS    (OPT_PPP_CODE | OPT_PPP_LENGTH | OPT_PPP_PPPTYPE)
>
> struct ethertypeent *ethent;
>
> static void print_help()
> {
>     printf(
> "ppp options:\n"
> "--ppp-code [!] code       : pppoe code identifier, \n"
> "--ppp-length [!] length   : pppoe length (integer)\n"
> "--ppp-ppptype [!] ppptype :PPP protocol (hexadecimal or name)\n");
> }
>
> static void init(struct ebt_entry_match *match)
> {
>     struct ebt_ppp_info *pppinfo = (struct ebt_ppp_info *) match->data;
>     pppinfo->invflags = 0;
>     pppinfo->bitmask = 0;
> }
>
>
> static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
>    unsigned int *flags, struct ebt_entry_match **match)
> {
>     struct ebt_ppp_info *pppinfo = (struct ebt_ppp_info *) (*match)->data;
>     char *end;
>     struct ebt_ppp_info local;
>
>     switch (c) {
>     case PPP_CODE:
>         ebt_check_option2(flags, OPT_PPP_CODE);
>         if (ebt_check_inverse2(optarg))
>             pppinfo->invflags |= EBT_PPP_CODE;
>         local.code = strtoul(optarg, &end, 10);
>         if (local.code >= 200 || *end != '\0')
>             ebt_print_error2("Invalid --code range <200 ('%s')", optarg);
>         pppinfo->code = local.code;
>         pppinfo->bitmask |= EBT_PPP_CODE;
>         break;
>
>     case PPP_LENGTH:
>
>         ebt_check_option2(flags, PPP_LENGTH);
>         if (ebt_check_inverse2(optarg))
>             pppinfo->invflags |= EBT_PPP_LENGTH;
>         local.length = strtoul(optarg, &end, 10);
>         if (local.length > 4094 || *end != '\0')
>             ebt_print_error2("Invalid --ppp-length range ('%s')", optarg);
>         pppinfo->length = local.length;
>         pppinfo->bitmask |= EBT_PPP_LENGTH;
>         break;
>     case PPP_PPPTYPE:
>         ebt_check_option2(flags, OPT_PPP_PPPTYPE);
>         if (ebt_check_inverse2(optarg))
>             pppinfo->invflags |= EBT_PPP_PPPTYPE;
>         local.ppptype = strtoul(optarg, &end, 16);
>         if (*end != '\0') {
>             ethent = getethertypebyname(optarg);
>             if (ethent == NULL)
>                 ebt_print_error("Unknown  value ('%s')", optarg);
>             local.ppptype = ethent->e_ethertype;
>         }
>         if (local.ppptype < ETH_ZLEN) //define ETH_ZLEN    6
>             ebt_print_error2("Invalid ---ppptype range ('%s')", optarg);
>         pppinfo->ppptype = htons(local.ppptype);
>         pppinfo->bitmask |= EBT_PPP_PPPTYPE;
>         break;
>     default:
>         return 0;
>
>     }
>     return 1;
> }
>
> static void final_check(const struct ebt_u_entry *entry,
>    const struct ebt_entry_match *match,
>    const char *name, unsigned int hookmask, unsigned int time)
> {
>     if (entry->ethproto != ETH_P_PPP_DISC || entry->invflags & EBT_IPROTO)
>         ebt_print_error("For ppp filtering the protocol must be specified as PPP_DISC or PPP_SES");
>
>     /* Check if specified vlan-id=0 (priority-tagged frame condition) 
>      * when vlan-prio was specified. */
>     /* I see no reason why a user should be prohibited to match on a perhaps impossible situation <BDS>
>     if (vlaninfo->bitmask & EBT_VLAN_PRIO &&
>         vlaninfo->id && vlaninfo->bitmask & EBT_VLAN_ID)
>         ebt_print_error("When setting --vlan-prio the specified --vlan-id must be 0");*/
> }
>
> static void print(const struct ebt_u_entry *entry,
>    const struct ebt_entry_match *match)
> {
>     struct ebt_ppp_info *pppinfo = (struct ebt_ppp_info *) match->data;
>
>     if (pppinfo->bitmask & EBT_PPP_CODE) {
>         printf("--ppp-code %s%d ", (pppinfo->invflags & EBT_PPP_CODE) ? "! " : "", pppinfo->code);
>     }
>     if (pppinfo->bitmask & EBT_PPP_LENGTH) {
>         printf("--ppp-length %s%d ", (pppinfo->invflags & EBT_PPP_LENGTH) ? "! " : "", pppinfo->length);
>     }
>     if (pppinfo->bitmask & EBT_PPP_PPPTYPE) {
>         printf("--ppp-ppptype %s", (pppinfo->invflags & EBT_PPP_PPPTYPE) ? "! " : "");
>         ethent = getethertypebynumber(ntohs(pppinfo->ppptype));
>         if (ethent != NULL) {
>             printf("%s ", ethent->e_name);
>         } else {
>             printf("%4.4X ", ntohs(pppinfo->ppptype));
>         }
>     }
> }
>
> static int compare(const struct ebt_entry_match *ppp1,
>    const struct ebt_entry_match *ppp2)
> {
>     struct ebt_ppp_info *pppinfo1 = (struct ebt_ppp_info *) ppp1->data;
>     struct ebt_ppp_info *pppinfo2 = (struct ebt_ppp_info *) ppp2->data;
>
>     if (pppinfo1->bitmask != pppinfo2->bitmask)
>         return 0;
>     if (pppinfo1->invflags != pppinfo2->invflags)
>         return 0;
>     if (pppinfo1->bitmask & EBT_PPP_CODE &&
>         pppinfo1->code != pppinfo2->code)
>         return 0;
>     if (pppinfo1->bitmask & EBT_PPP_LENGTH &&
>         pppinfo1->length != pppinfo2->length)
>         return 0;
>     if (pppinfo1->bitmask & EBT_PPP_PPPTYPE &&
>         pppinfo1->ppptype != pppinfo2->ppptype)
>         return 0; 
>     return 1;
> }
>
> static struct ebt_u_match ppp_match = {
>     .name        = "ppp",
>     .size        = sizeof(struct ebt_ppp_info),
>     .help        = print_help,
>     .init        = init,
>     .parse        = parse,
>     .final_check    = final_check,
>     .print        = print,
>     .compare    = compare,
>     .extra_ops    = opts,
> };
>
> void _init(void)
> {
>     ebt_register_match(&ppp_match);
> }
>
>
> -------------------------------------------------------
> #ifndef __LINUX_BRIDGE_EBT_PPP_H
> #define __LINUX_BRIDGE_EBT_PPP_H
>
> #define EBT_PPP_CODE    0x01
> #define EBT_PPP_LENGTH    0x02
> #define EBT_PPP_PPPTYPE    0x04
> #define EBT_PPP_MASK (EBT_PPP_CODE| EBT_PPP_LENGTH | EBT_PPP_PPPTYPE)
> #define EBT_PPP_MATCH "ppp"
>
>
> struct ebt_ppp_info
>
> {
>
>   uint8_t vertype
>   uint8_t code; //PADO O7:7  //PADS 65 :101(dec) //ETH:8863
>
>   uint16_t session;
>
>   uint16_t length;/
>   unsigned short int ppptype;  
>
>   uint8_t bitmask;        /* Args bitmask bit 1=1 - ID arg,
>                bit 2=1 User-Priority arg, bit 3=1 encap*/
>   uint8_t invflags;
>
> };
> #endif
>
>
>
> I have added to Makefile like this: EXT_FUNC+=802_3 nat arp arpreply ip ip6 standard log redirect vlan mark_m mark ppp \
>           pkttype stp among limit ulog nflog  and it compiled with no issue.
>
>  But when I launch this command line for example : 
> ./ebtables -A FORWARD -p PPP_DISC --ppp-code 7 -j DROP                      // DROP PADO frames if it works
>
> A message appears:
> "The kernel doesn't support a certain ebtables extension, consider recompiling your kernel or insmod the extension"
> (see communication.c)
>
>
> I think it is due to the size of the structure ebt_ppp_info
>
> defined in ebt_ppp.h but I do not understand. Can anybody help me to understand please?
>
> Is there other easy way to filter specific ppp packet ?
>
> Thanks,
>
> Eric 
>
>
>
>
>
>
>
>
>
>
>  		 	   		  
> _________________________________________________________________
> Your E-mail and More On-the-Go. Get Windows Live Hotmail Free.
> https://signup.live.com/signup.aspx?id=60969
>   
> ------------------------------------------------------------------------
>
> ------------------------------------------------------------------------------
> ThinkGeek and WIRED's GeekDad team up for the Ultimate 
> GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the 
> lucky parental unit.  See the prize list and enter to win: 
> http://p.sf.net/sfu/thinkgeek-promo
> ------------------------------------------------------------------------
>
> _______________________________________________
> Ebtables-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/ebtables-devel
>   


-- 
Bart De Schuymer
www.artinalgorithms.be


------------------------------------------------------------------------------
ThinkGeek and WIRED's GeekDad team up for the Ultimate 
GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the 
lucky parental unit.  See the prize list and enter to win: 
http://p.sf.net/sfu/thinkgeek-promo