Browse Source

Added dual Qtag support.

AdrianSimionov 11 years ago
parent
commit
f66a531c02

BIN
regression/docsis2.0_L2VPN_DualQTag.regression


+ 1 - 1
src/docsis_common.h

@@ -31,7 +31,7 @@
 
 
 #ifndef NUM_IDENTIFIERS
-#define NUM_IDENTIFIERS 210
+#define NUM_IDENTIFIERS 211
 #endif /*  NUM_IDENTIFIERS, needed in docsis_symtable.h  */
 
 #define MAXINT 2000000000

+ 9 - 0
src/docsis_decode.c

@@ -120,6 +120,15 @@ void decode_ether (unsigned char *tlvbuf, symbol_type *sym, size_t length )
 	sym->sym_ident, ether_ntoa(tlvbuf) );
 }
 
+void decode_dual_qtag (unsigned char *tlvbuf, symbol_type *sym, size_t length )
+{
+    if (length != 4 ) {
+        fprintf(stderr, "dual qtag length mismatch\n");
+        exit(-45);
+    }
+    printf("%s %d,%d;\n", sym->sym_ident, tlvbuf[0] * 256 + tlvbuf[1], tlvbuf[2]*256 + tlvbuf[3]);
+}
+
 void decode_ethermask (unsigned char *tlvbuf, symbol_type *sym, size_t length)
 {
 /* the return value of ether_ntoa is a pointer to a static string

+ 1 - 0
src/docsis_decode.h

@@ -35,6 +35,7 @@ void decode_uchar (unsigned char *tlvbuf, symbol_type *sym, size_t length );
 void decode_ip (unsigned char *tlvbuf, symbol_type *sym, size_t length );
 void decode_ip6 (unsigned char *tlvbuf, symbol_type *sym, size_t length );
 void decode_ether (unsigned char *tlvbuf, symbol_type *sym, size_t length );
+void decode_dual_qtag (unsigned char *tlvbuf, symbol_type *sym, size_t length );
 void decode_ethermask (unsigned char *tlvbuf, symbol_type *sym, size_t length );
 void decode_md5 (unsigned char *tlvbuf, symbol_type *sym, size_t length);
 void decode_snmp_wd (unsigned char *tlvbuf, symbol_type *sym, size_t length);

+ 26 - 0
src/docsis_encode.c

@@ -219,6 +219,32 @@ union t_val *helper; /* We only use this to cast the void* we receive to what we
   return retval;  /* hopefully this equals 6 :) */
 }
 
+int encode_dual_qtag ( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
+{
+  int i, final;
+  char *token;
+  char *array[2];
+  const char s[2] = ",";
+  union t_val *helper;
+
+#ifdef DEBUG
+    fprintf(stderr, "encode_dual_qtag: found '%s' on line %d\n", helper->strval, line );
+#endif /* DEBUG */
+
+    helper = (union t_val *) tval;
+    i = 0;
+    token = strtok(helper->strval, s);
+    while (token != NULL)
+    {
+       array[i++] = token;
+       token = strtok (NULL, s);
+    }
+    final = htonl(atoi(array[0]) << 16 | atoi(array[1]));
+    memcpy (buf, &final, sizeof(final));
+    free(helper->strval);
+    return (sizeof(final));
+}
+
 int encode_ethermask ( unsigned char *buf, void *tval, struct symbol_entry *sym_ptr )
 {
 int reta, retb; 	     /* return value of ether_aton */

+ 1 - 0
src/docsis_encode.h

@@ -31,6 +31,7 @@ int encode_uchar  	(unsigned char *buf, void *tval, struct symbol_entry *sym_ptr
 int encode_ip     	(unsigned char *buf, void *tval, struct symbol_entry *sym_ptr );
 int encode_ip6     	(unsigned char *buf, void *tval, struct symbol_entry *sym_ptr );
 int encode_ether	(unsigned char *buf, void *tval, struct symbol_entry *sym_ptr );
+int encode_dual_qtag	(unsigned char *buf, void *tval, struct symbol_entry *sym_ptr );
 int encode_ethermask	(unsigned char *buf, void *tval, struct symbol_entry *sym_ptr );
 int encode_string 	(unsigned char *buf, void *tval, struct symbol_entry *sym_ptr );
 int encode_strzero	(unsigned char *buf, void *tval, struct symbol_entry *sym_ptr );

+ 1 - 0
src/docsis_lex.l

@@ -151,6 +151,7 @@ TlvType			{ return T_TLV_TYPE;		}
 ;	 { yylval.strval=yytext;return ';'; }
 .	 { fprintf(stderr, "Unrecognized char \"%c\" at line %d\n",*yytext,line); exit(-1); }
 (::|(([a-fA-F0-9]{1,4}):){7}(([a-fA-F0-9]{1,4}))|(:(:([a-fA-F0-9]{1,4})){1,6})|((([a-fA-F0-9]{1,4}):){1,6}:)|((([a-fA-F0-9]{1,4}):)(:([a-fA-F0-9]{1,4})){1,6})|((([a-fA-F0-9]{1,4}):){2}(:([a-fA-F0-9]{1,4})){1,5})|((([a-fA-F0-9]{1,4}):){3}(:([a-fA-F0-9]{1,4})){1,4})|((([a-fA-F0-9]{1,4}):){4}(:([a-fA-F0-9]{1,4})){1,3})|((([a-fA-F0-9]{1,4}):){5}(:([a-fA-F0-9]{1,4})){1,2}))		{ TSAVE(yytext);yylval.strval=tsave; return T_IP6;	  }
+[0-9]+,[0-9]+ 				{ TSAVE(yytext);yylval.strval=tsave; return T_DUAL_TAG; }
 %%
 
 struct symbol_entry

+ 2 - 0
src/docsis_symtable.h

@@ -306,6 +306,8 @@ symbol_type symtable[NUM_IDENTIFIERS] =  {
 { 206,  "L2VPNEncoding",               5,    204,  (encode_nothing),  (decode_aggregate),  0,         0          }, /* 23.43.5 */
 { 207,  "VPNIdentifier",               1,    206,  (encode_string),   (decode_string),     4,         255        }, /* 23.43.5.1 */
 
+{ 191,  "NSIEncapsulationDualQTag",    3,    190,  (encode_dual_qtag),   (decode_dual_qtag),  0,         0          },
+
 /* Generic TLV ... we only use the limits, code and length don't matter ...*/
 { 998, "GenericTLV",           		0, 0,     (encode_nothing),   (decode_special),  0,        0        },
 { 999, "/*EndOfDataMkr*/",     		255, 0,   (encode_nothing),   (decode_special),  0,        0          }

+ 3 - 1
src/docsis_yy.y

@@ -95,7 +95,7 @@ struct tlv *_my_tlvtree_head;
 %token <uintval>  T_TLV_STR_VALUE
 %token <uintval>  T_TLV_STRZERO_VALUE
 %token <uintval>  T_TLV_TYPE
-
+%token <uintval>  T_DUAL_TAG
 
 %type <tlvptr>  assignment_stmt
 %type <tlvptr>  generic_stmt
@@ -171,6 +171,8 @@ assignment_stmt:  T_IDENTIFIER T_INTEGER ';' {
 			$$ = create_tlv ($1, (union t_val *)&$2);}
 		| T_IDENTIFIER T_IP6 ';' {
 			$$ = create_tlv ($1, (union t_val *)&$2);}
+		| T_IDENTIFIER T_DUAL_TAG ';' {
+			$$ = create_tlv ($1, (union t_val *)&$2);}
 		| T_IDENTIFIER T_MAC ';' {
 			$$ = create_tlv ($1, (union t_val *)&$2);}
 		| T_IDENTIFIER T_ETHERMASK ';' {