http://gimel.esc.cam.ac.uk/james/rpld/src/rpld-1.5.tar.gz
[rpld.git] / rpld_conf.y
index ece011d..b8239c2 100644 (file)
@@ -2,9 +2,9 @@
 *     rpld - an IBM style RIPL server            *
 *************************************************/
 
-/* Copyright (c) 1999, James McKenzie.
+/* Copyright (c) 1999,2000, James McKenzie.
  *                      All rights reserved
- * Copyright (c) 1998, Christopher Lightfoot.
+ * Copyright (c) 1998,2000, Christopher Lightfoot.
  *                      All rights reserved
  *
  * By using this file, you agree to the terms and conditions set
  *     YACC grammar for RPLD conf file parser
  *
  * $Log: rpld_conf.y,v $
+ * Revision 1.7  2000/07/23 19:14:19  root
+ * #
+ *
+ * Revision 1.6  2000/07/17 11:59:45  root
+ * #
+ *
+ * Revision 1.5  2000/07/17 10:43:34  root
+ * #
+ *
+ * Revision 1.4  2000/07/16 14:05:28  root
+ * #
+ *
  * Revision 1.3  2000/07/16 13:18:10  root
  * #
  *
@@ -63,7 +75,7 @@
 
 %{
 
-static char rcsid[]="$Id: rpld_conf.y,v 1.3 2000/07/16 13:18:10 root Exp root $";
+static char rcsid[]="$Id: rpld_conf.y,v 1.7 2000/07/23 19:14:19 root Exp $";
 
 #include "project.h"
 
@@ -76,13 +88,17 @@ typedef enum {INIT, GLOBALBLOCK, HOSTBLOCK, FILEBLOCK} STATE ;
 
 %}
 
-%token BLOCK_START BLOCK_END NAME TEXT NUMBER MACADDR
+%token BLOCK_START BLOCK_END NAME TEXT NUMBER MACADDR MACADDR_PARTIAL
 
 %union {
                long number;
                char *name;
                char *text;
                char mac_address[6];
+               struct partial_mac {
+                       char mac_address[6];
+                       int mac_len;
+               } pm;
        }
 
 %start block_list
@@ -108,6 +124,7 @@ statement:  NAME                    { process_thing(ASSERTION, $1.name, 0, NULL); }
        |       NAME '=' TEXT           { process_thing(ASSIGNMENT, $1.name, TEXT, &$3); }
        |       NAME '=' NUMBER         { process_thing(ASSIGNMENT, $1.name, NUMBER, &$3); }
        |       NAME '=' MACADDR        { process_thing(ASSIGNMENT, $1.name, MACADDR, &$3); }
+       |       NAME '=' MACADDR_PARTIAL        { process_thing(ASSIGNMENT, $1.name, MACADDR_PARTIAL, &$3); }
        |       block
 
 %%
@@ -149,6 +166,8 @@ struct clientinfo
        // optional
        int have_framesize;
        int have_blocksize;
+       int have_pacing;
+       int have_nospew;
 };
 
 struct clfileinfo
@@ -201,6 +220,7 @@ void process_thing(THING thing, char *name, int type, YYSTYPE *pvalue)
 
                                pc->blocklen=MY_BLOCK_LEN;
                                pc->framelen=MY_FRAME_LEN;
+                               pc->pacing=MY_PACING;
                                
                                state = HOSTBLOCK;
                                break;
@@ -276,7 +296,12 @@ void process_thing(THING thing, char *name, int type, YYSTYPE *pvalue)
                        THROW_ERROR("Unknown directive");
                } else if (state == HOSTBLOCK) {
                        // no host assertions ATM
-                       THROW_ERROR("Unknown directive");
+                       if (strsame(name,"nospew")) {
+                               if (ci.have_pacing) THROW_ERROR("Directive nospew incompatible with pacing ");
+                               if (ci.have_nospew) THROW_ERROR("Repeated directive");
+                               ci.have_nospew=1;
+                               pc->nospew++;
+                       } else THROW_ERROR("Unknown directive");
                } else if (state == FILEBLOCK) {
                        if (strsame(name,"linux")) {
                                if (!cfi.have_path) THROW_ERROR("A path to a
@@ -287,7 +312,7 @@ valid kernel must precede linux");
                                cfi.have_offset=1;
                                cfi.have_length=1;
                                ci.have_run_addr=1;
-                       } else{
+                       }else{
                        THROW_ERROR("Unknown directive");
                        }
                } else THROW_ERROR("Unknown directive");
@@ -300,11 +325,19 @@ valid kernel must precede linux");
                } else if (state == HOSTBLOCK) {
                        // ethernet address
                        if (strsame(name, "ethernet") || strsame(name, "mac")) {
-                               if (type != MACADDR) THROW_ERROR("Directive must be followed by an ethernet address");
+                               if (type != MACADDR && type != MACADDR_PARTIAL)
+                                       THROW_ERROR("Directive must be followed by a (partial or complete) ethernet address");
                                else if (ci.have_mac) THROW_ERROR("Repeated directive");
 
-                               // set MAC address
-                               bcopy(pvalue->mac_address,pc->mac,ETH_ALEN);
+                               if (type == MACADDR) {
+                                       // set MAC address; this is non-partial, so len = ETH_ALEN
+                                       bcopy(pvalue->mac_address, pc->mac, ETH_ALEN);
+                                       pc->partial_mac_len = ETH_ALEN;
+                               } else {
+                                       bcopy(pvalue->pm.mac_address, pc->mac, pvalue->pm.mac_len);
+                                       pc->partial_mac_len = pvalue->pm.mac_len;
+                               }
+
                                ci.have_mac = 1;
                        }
                        // execute address
@@ -332,6 +365,13 @@ valid kernel must precede linux");
                                pc->framelen = pvalue->number;
                                ci.have_framesize = 1;
                        }
+                       else if (strsame(name,"pacing")) {
+                               if (type != NUMBER) THROW_ERROR("Directive must be followed by an integer ");
+                               if (ci.have_nospew) THROW_ERROR("Directive pacing incompatible with nospew ");
+                               if (ci.have_pacing) THROW_ERROR("Repeated directive");
+                               pc->pacing = pvalue->number;
+                               ci.have_pacing =1;
+                       }
                        else THROW_ERROR("Unknown directive");
                } else if (state == FILEBLOCK) {
                        // path