PKCS15 PKCS15Object tagging misunderstanding - tagging

While doing with ASN.1 and decoding the PKCS #15 token, I've found that I do not understand why tags [0] and [1] of the PKCS15Object are EXPLICIT and not implicit, as it declared whit DEFINITIONS IMPLICIT TAGS clause.
PKCS-15 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
pkcs-15(15) modules(1) pkcs-15(1)}
-- $Revision: 1.7 $ --
DEFINITIONS IMPLICIT TAGS ::=
...
PKCS15Object {ClassAttributes, SubClassAttributes, TypeAttributes}
::= SEQUENCE {
commonObjectAttributes CommonObjectAttributes,
classAttributes ClassAttributes,
subClassAttributes [0] SubClassAttributes OPTIONAL <<--- explicit?,
typeAttributes [1] TypeAttributes <<--- explicit?
}
PrivateKeyObject {KeyAttributes} ::= PKCS15Object {
CommonKeyAttributes, CommonPrivateKeyAttributes, KeyAttributes}
PrivateKeys ::= PathOrObjects {PrivateKeyType}
PrivateKeyType ::= CHOICE {
privateRSAKey PrivateKeyObject {PrivateRSAKeyAttributes},
privateECKey [0] PrivateKeyObject {PrivateECKeyAttributes},
... -- For future extensions
}
PrivateRSAKeyAttributes ::= SEQUENCE {
value ObjectValue {RSAPrivateKeyObject},
modulusLength INTEGER, -- modulus length in bits, e.g. 1024
keyInfo KeyInfo {NULL, PublicKeyOperations} OPTIONAL,
... -- For future extensions
}
Please, someone, explain it to me.

It is due to rule 31.2.7 (c) in X.680. You have an untagged DummyReference that you are tagging, so your tag is made explicit.

Related

Convert string to XML format in C language

I have a question, is there an algorithm that converts the corresponding logical expression as a string to xml format?
For example:
I am loading logical expressions as a string from the input file:
(X&Y)|Z
And now to convert it into xml format, to get something like this in a new file:
<expression>
<or>
<operand>Z</operand>
<and>
<operand>X</operand>
<operand>Y</operand>
</and>
</or>
</expression>
Thanks in advance!
(Responding to the xml tag.)
Perhaps you can make use of invisible-xml (ixml),
the SO Info
tab lists several resources.
With a grammar such as
ixml version "1.0".
expression: expr.
-expr: operand; and; or; not.
and: expr, -"&", expr.
or: expr, -"|", expr.
not: -"!", operand.
-operand: id; -"(", expr, -")".
id: letter.
-letter: ["A"-"Z"].
the ixml processor coffeepot
java -jar '/usr/local/share/java/coffeepot-1.99.11.jar' \
--grammar:expr-bool.ixml --pretty-print '(X&Y)|Z'
produces the following output:
<expression>
<or>
<and>
<id>X</id>
<id>Y</id>
</and>
<id>Z</id>
</or>
</expression>
With the input (X&Y)|Z&!(A|B) coffeepot (by default) outputs the
first of (in this case 2) possible parses and emits the root element as
<expression xmlns:ixml="http://invisiblexml.org/NS" ixml:state="ambiguous">
to point out the ambiguity.
If parsing fails the output could be something like:
<fail xmlns:ixml="http://invisiblexml.org/NS" ixml:state="failed">
<line>1</line>
<column>14</column>
<pos>14</pos>
<end-of-input>true</end-of-input>
<permitted>['A'-'Z']</permitted>
</fail>

Force ANTLR (version 3) to match lexer rule

I have the following ANTLR (version 3) grammar:
grammar GRM;
options
{
language = C;
output = AST;
}
create_statement : CREATE_KEYWORD SPACE_KEYWORD FILE_KEYWORD SPACE_KEYWORD value -> ^(value);
value : NUMBER | STRING;
CREATE_KEYWORD : 'CREATE';
FILE_KEYWORD : 'FILE';
SPACE_KEYWORD : ' ';
NUMBER : DIGIT+;
STRING : (LETTER | DIGIT)+;
fragment DIGIT : '0'..'9';
fragment LETTER : 'a'..'z' | 'A'..'Z';
With this grammar, I am able to successfully parse strings like CREATE FILE dump or CREATE FILE output. However, when I try to parse a string like CREATE FILE file it doesn't work. ANTLR matches the text file (in the string) with lexer rule FILE_KEYWORD which is not the match that I was expecting. I was expecting it to match with lexer rule STRING.
How can I force ANTLR to do this?
Your problem is a variant on classic contextual keyword vs identifier issue, it seems.
Either "value" should be a lexer rule, not a parser rule, it's too late otherwise, or you should reorder the rules (or both).
Hence using VALUE = NUMBER | STRING (lexer rule) instead of lower case value (grammar rule) will help. The order of the lexer rules are also important, usually definition of ID ("VALUE" in your code) comes after keyword definitions.
See also : 'IDENTIFIER' rule also consumes keyword in ANTLR Lexer grammar
grammar GMR;
options
{
language = C;
output = AST;
}
create_statement : CREATE_KEYWORD SPACE_KEYWORD FILE_KEYWORD SPACE_KEYWORD value -> ^(value);
CREATE_KEYWORD : 'CREATE';
FILE_KEYWORD : 'FILE';
value : (LETTER | DIGIT) + | FILE_KEYWORD | CREATE_KEYWORD ;
SPACE_KEYWORD : ' ';
this works for me in ANTLRworks for input CREATE FILE file and for input CREATE FILE FILE if needed.

Net-SNMP: snmpbulkget - genError failure

I am attempting to implement Net-SNMP 5.7.3 on a 64-bit Linux server. Currently I hit a road-block in not being able to determine why my Linux server returns an error code whenever a getBulkRequest comes in for OID that has MIBs underneath it. I am able to get the info for each MIB when I use snmpget against its corresponding OID, but when I perform snmpbulkget, I keep getting
Error in packet.
Reason: (genError) A general failure occured
Failed object: MY-ELEMENT-MIB::myModel.0
I think my problem lies in my Agent's SNMP configuration file, but I have been unable to resolve this. Anyhow, in case I am wrong, I am posting everything I have done thus far. Hopefully my "cleaned up" code makes it easier to follow and helps someone else out in the future; I struggled to get this far.
My snmp.conf I used to startup my Agent (placed in /etc/snmp/). I am using v2c and leaving it open to public.
###############################################################################
#
# EXAMPLE.conf:
# An example configuration file for configuring the Net-SNMP agent ('snmpd')
# See the 'snmpd.conf(5)' man page for details
#
# Some entries are deliberately commented out, and will need to be explicitly activated
#
###############################################################################
#
# AGENT BEHAVIOUR
#
# Listen for connections from the local system only
#agentAddress udp:127.0.0.1:161
# Listen for connections on all interfaces (both IPv4 *and* IPv6)
agentAddress udp:161,udp6:[::1]:161
###############################################################################
#
# ACCESS CONTROL
#
####
# First, map the community name (COMMUNITY) into a security name
# (local and mynetwork, depending on where the request is coming
# from):
# sec.name source community
com2sec local localhost secret42
com2sec cust1_sec default public
####
# Second, map the security names into group names:
# sec.model sec.name
group MyRWGroup v1 local
group MyRWGroup v2c local
group cust1_grp v1 cust1_sec
group cust1_grp v2c cust1_sec
####
# Third, create a view for us to let the groups have rights to:
# incl/excl subtree mask
view all included .1
#view cust1_v excluded .1
#view cust1_v included sysUpTime.0
#view cust1_v included interfaces.ifTable.ifEntry.ifIndex.1 ff.a0
####
# Finally, grant the groups access to their views:
# context sec.model sec.level match read write notif
access MyRWGroup "" any noauth exact all all none
access cust1_grp "" any noauth exact all all none
# Full read-only access for SNMPv3
#rouser authOnlyUser
# Full write access for encrypted requests
# Remember to activate the 'createUser' lines above
#rwuser authPrivUser priv
###############################################################################
#
# SYSTEM INFORMATION
#
# Note that setting these values here, results in the corresponding MIB objects being 'read-only'
# See snmpd.conf(5) for more details
sysLocation Server Room
sysContact Me <me#example.org>
# Application + End-to-End layers
sysServices 72
###############################################################################
#
# ACTIVE MONITORING
#
# send SNMPv1 traps
#trapsink localhost:162 public
# send SNMPv2c traps
#trap2sink localhost public
# send SNMPv2c INFORMs
#informsink localhost public
# Note that you typically only want *one* of these three lines
# Uncommenting two (or all three) will result in multiple copies of each notification.
#
# Event MIB - automatically generate alerts
#
# Remember to activate the 'createUser' lines above
#iquerySecName internalUser
#rouser internalUser
# generate traps on UCD error conditions
#defaultMonitors yes
# generate traps on linkUp/Down
#linkUpDownNotifications yes
###############################################################################
#
# EXTENDING THE AGENT
#
#
# AgentX Sub-agents
#
# Run as an AgentX master agent
master agentx
# Listen for network connections (from localhost)
# rather than the default named socket /var/agentx/master
#agentXSocket tcp:localhost:705
After I startup snmpd (the Agent), I startup a sub-Agent Daemon in my C++ application. Here is the Daemon example I followed
http://www.net-snmp.org/tutorial/tutorial-5/toolkit/demon/example-demon.c
Here is the C++ sub-Agent code I implemented. Daemon calls my init_myMibSubAgent() instead of init_nstAgentSubagentObject().
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "myMibSubAgent.h"
#include "SNMPAppData.h"
#include <string>
using namespace std;
void CMyMibSubAgent::init_myMibSubAgent(void)
{
static oid myGeneral_oid[] = { 1, 3, 6, 1, 4, 1, 1234, 2, 1, 2};
// myModel; DisplayString
static oid myModel_oid[] = { 1, 3, 6, 1, 4, 1, 1234, 2, 1, 2, 1}; // We dont add 0 to end of watch scalar registration oid
netsnmp_register_watched_scalar(
netsnmp_create_handler_registration("myModel", NULL,
myModel_oid, OID_LENGTH(myModel_oid),
HANDLER_CAN_RWRITE),
netsnmp_create_watcher_info(&gSNMPAppData.myGeneral.data.myModel, sizeof(gSNMPAppData.myGeneral.data.myModel),
ASN_OCTET_STR, WATCHER_SIZE_STRLEN));
// mySerialCode; DisplayString
static oid mySerialCode_oid[] = { 1, 3, 6, 1, 4, 1, 1234, 2, 1, 2, 2}; // We dont add 0 to end of watch scalar registration oid
netsnmp_register_watched_scalar(
netsnmp_create_handler_registration("mySerialCode", NULL,
mySerialCode_oid, OID_LENGTH(mySerialCode_oid),
HANDLER_CAN_RWRITE),
netsnmp_create_watcher_info(&gSNMPAppData.myGeneral.data.mySerialCode, sizeof(gSNMPAppData.myGeneral.data.mySerialCode),
ASN_OCTET_STR, WATCHER_SIZE_STRLEN));
// myType; INTEGER
static oid myType_oid[] = { 1, 3, 6, 1, 4, 1, 1234, 2, 1, 2, 3, 0};
netsnmp_register_int_instance("myType", myType_oid, OID_LENGTH(myType_oid), &gSNMPAppData.myGeneral.data.myType, NULL );
// mySoftwareRev; DisplayString
static oid mySoftwareRev_oid[] = { 1, 3, 6, 1, 4, 1, 1234, 2, 1, 2, 4}; // We dont add 0 to end of watch scalar registration oid
netsnmp_register_watched_scalar(
netsnmp_create_handler_registration("mySoftwareRev", NULL,
mySoftwareRev_oid, OID_LENGTH(mySoftwareRev_oid),
HANDLER_CAN_RWRITE),
netsnmp_create_watcher_info(&gSNMPAppData.myGeneral.data.mySoftwareRev, sizeof(gSNMPAppData.myGeneral.data.mySoftwareRev),
ASN_OCTET_STR, WATCHER_SIZE_STRLEN));
// myState; INTEGER
static oid myState_oid[] = { 1, 3, 6, 1, 4, 1, 1234, 2, 1, 2, 5, 0};
netsnmp_register_int_instance("myState", myState_oid, OID_LENGTH(myState_oid), &gSNMPAppData.myGeneral.data.myState, NULL );
// mySeverityLevel; INTEGER
//static oid mySeverityLevel_oid[] = { 1, 3, 6, 1, 4, 1, 1234, 2, 1, 2, 6, 0};
//netsnmp_register_int_instance("mySeverityLevel", mySeverityLevel_oid, OID_LENGTH(mySeverityLevel_oid), &gSNMPAppData.myGeneral.data.mySeverityLevel, NULL );
// myAssetTag; DisplayString
static oid myAssetTag_oid[] = { 1, 3, 6, 1, 4, 1, 1234, 2, 1, 2, 7}; // We dont add 0 to end of watch scalar registration oid
netsnmp_register_watched_scalar(
netsnmp_create_handler_registration("myAssetTag", NULL,
myAssetTag_oid, OID_LENGTH(myAssetTag_oid),
HANDLER_CAN_RWRITE),
netsnmp_create_watcher_info(&gSNMPAppData.myGeneral.data.myAssetTag, sizeof(gSNMPAppData.myGeneral.data.myAssetTag),
ASN_OCTET_STR, WATCHER_SIZE_STRLEN));
// myTtMaxTargets; Integer32
static oid myTtMaxTargets_oid[] = { 1, 3, 6, 1, 4, 1, 1234, 2, 1, 3, 1, 0};
netsnmp_register_int_instance("myTtMaxTargets", myTtMaxTargets_oid, OID_LENGTH(myTtMaxTargets_oid), &gSNMPAppData.myTrapTargets.data.myTtMaxTargets, NULL );
// myTtCfgTableNextIndex; Integer32
static oid myTtCfgTableNextIndex_oid[] = { 1, 3, 6, 1, 4, 1, 1234, 2, 1, 3, 2, 0};
netsnmp_register_int_instance("myTtCfgTableNextIndex", myTtCfgTableNextIndex_oid, OID_LENGTH(myTtCfgTableNextIndex_oid), &gSNMPAppData.myTrapTargets.data.myTtCfgTableNextIndex, NULL );
// myTtCfgTable
for (int i=0; i < vsmNcIpCfgEntry_MAXROWS; i++)
{
// myTtCfgIndex; Integer32
//static oid myTtCfgIndex_oid[] = { 1, 3, 6, 1, 4, 1, 1234, 2, 1, 3, 3, 1, 1, i+1};
//string myTtCfgIndexStr = "myTtCfgIndex."+i;
//netsnmp_register_int_instance(myTtCfgIndexStr.c_str(), myTtCfgIndex_oid, OID_LENGTH(myTtCfgIndex_oid), &gSNMPAppData.vsmNcIpCfgEntry.data[i].myTtCfgIndex, NULL );
// myTtCfgIpAddress; IpAddress
oid myTtCfgIpAddress_oid[] = { 1, 3, 6, 1, 4, 1, 1234, 2, 1, 3, 3, 1, 2, i+1};
string myTtCfgIpAddressStr = "myTtCfgIpAddress." + std::to_string(i);
netsnmp_register_handler(
netsnmp_create_handler_registration(myTtCfgIpAddressStr.c_str(), handle_myTtCfgIpAddress,
myTtCfgIpAddress_oid, OID_LENGTH(myTtCfgIpAddress_oid), HANDLER_CAN_RWRITE));
// myTtCfgCommunity; OCTET STRING
oid myTtCfgCommunity_oid[] = { 1, 3, 6, 1, 4, 1, 1234, 2, 1, 3, 3, 1, 3, i+1};
string myTtCfgCommunityStr = "myTtCfgCommunity." + std::to_string(i);
netsnmp_register_watched_instance(
netsnmp_create_handler_registration(myTtCfgCommunityStr.c_str(), NULL,
myTtCfgCommunity_oid, OID_LENGTH(myTtCfgCommunity_oid),
HANDLER_CAN_RWRITE),
netsnmp_create_watcher_info(&gSNMPAppData.myTtCfgEntry.data[i].myTtCfgCommunity, sizeof(gSNMPAppData.myTtCfgEntry.data[i].myTtCfgCommunity),
ASN_OCTET_STR, WATCHER_SIZE_STRLEN));
// myTtCfgEntryStatus; RowStatus
oid myTtCfgEntryStatus_oid[] = { 1, 3, 6, 1, 4, 1, 1234, 2, 1, 3, 3, 1, 4, i+1};
string myTtCfgEntryStatusStr = "myTtCfgEntryStatus." + std::to_string(i);
netsnmp_register_int_instance(myTtCfgEntryStatusStr.c_str(), myTtCfgEntryStatus_oid, OID_LENGTH(myTtCfgEntryStatus_oid), &gSNMPAppData.myTtCfgEntry.data[i].myTtCfgEntryStatus, NULL );
}
}
int CMyMibSubAgent::handle_myTtCfgIpAddress(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
switch(reqinfo->mode)
{
case MODE_GET:
{
snmp_set_var_typed_value(requests->requestvb, ASN_IPADDRESS,
(u_char *)&gSNMPAppData.vsmNcIpCfgEntry.data[1].vsmIpAddress,
sizeof(gSNMPAppData.vsmNcIpCfgEntry.data[1].vsmIpAddress));
}
break;
case MODE_SET_RESERVE1:
break;
case MODE_SET_RESERVE2:
break;
case MODE_SET_FREE:
break;
case MODE_SET_ACTION:
break;
case MODE_SET_COMMIT:
break;
case MODE_SET_UNDO:
break;
default:
return SNMP_ERR_GENERR;
}
return SNMP_ERR_NOERROR;
}
Finally, here is the MIB module I placed in my Manager /usr/share/snmp/mibs/ directory that invokes the snmpbulkget and snmpget
--
-- Common Object Definitions for My Element MIB
--
MY-ELEMENT-MIB DEFINITIONS ::= BEGIN
-- Relationship to Other MIBs
--
--
-- The objects defined in this MIB are located under the
-- private.enterprises subtree as shown below:
--
-- iso(1).org(3).dod(6).internet(1)
-- |
-- private(4)
-- |
-- enterprises(1)
-- |
-- myOID(1234)
-- |
-- myRegistrations(2)
-- |
-- myElementMIB(1)
--
--
--
-- Object Synopsis
--
--
-- All objects within this MIB are prefixed with the OBJECT
-- IDENTIFIER "p", where "p" is:
--
-- iso(1).org(3).dod(6).internet(1).private(4).enterprises(1).
-- myOID(1234).myRegistrations(2).myElementMIB(1)
--
-- or, 1.3.6.1.4.1.1234.2.1
--
--
-- Object Name Object Id
-- ================================ ==============
--
-- myMIBNotifications p.0
-- myStateChange p.0.1
-- myGeneral p.2
-- myModel p.2.1.0
-- mySerialCode p.2.2.0
-- myType p.2.3.0
-- mySoftwareRev p.2.4.0
-- myState p.2.5.0
-- mySeverityLevel p.2.6.0
-- myAssetTag p.2.7.0
-- myTrapTargets p.3
-- myTtMaxTargets p.3.1.0
-- myTtCfgTableNextIndex p.3.2.0
-- myTtCfgTable p.3.3
-- myTtCfgEntry p.3.3.1
-- myTtCfgIndex p.3.3.1.1.n
-- myTtCfgIpAddress p.3.3.1.2.n
-- myTtCfgCommunity p.3.3.1.3.n
-- myTtCfgEntryStatus p.3.3.1.4.n
--
IMPORTS
MODULE-IDENTITY, NOTIFICATION-TYPE, OBJECT-TYPE,
IpAddress, TimeTicks, Integer32
FROM SNMPv2-SMI
TEXTUAL-CONVENTION,
DisplayString, RowStatus
FROM SNMPv2-TC
myRegistrations
FROM MY-REG;
myElementMIB MODULE-IDENTITY
LAST-UPDATED "200503230000Z"
ORGANIZATION "My Solutions, Inc."
CONTACT-INFO
"
My Solutions, Inc.
123 Smith Ave
Los Angeles, CA 12345,
USA.
phone: +1 (123) 123-4567
e-mail: me#example.org
http://www.website.com/support"
DESCRIPTION
"This MIB module describes the generic
characteristics of a manageable physical
element beneath the my enterprise."
REVISION "9911120000Z"
DESCRIPTION
"First draft."
REVISION "200004100000Z"
::= { myRegistrations 1 }
--
-- Element MIB Textual Conventions
--
MyFloatingPoint ::= TEXTUAL-CONVENTION
DISPLAY-HINT
"63a"
STATUS current
DESCRIPTION
"FloatingPoint provides a way of representing
non-integer numbers in SNMP. Numbers are
represented as a string of ASCII characters in
the natural way. So for example, '3', '3.142'
and '0.3142E1' are all valid numbers.
The syntax for the string is as follows. []
enclose an optional element, | is the separator
for a set of alternatives. () enclose syntax
which is to be viewed as a unit.
FloatingPoint ::= [Sign]
(Float1 | Float2 | DigitSequence)
[ExponentPart]
Float1 ::= DigitSequence '.' [DigitSequence]
Float2 ::= '.' DigitSequence
DigitSequence ::= Digit [DigitSequence]
ExponentPart ::= ('e' | 'E') [Sign] DigitSequence
Digit ::= '0'..'9'
Sign ::= '+' | '-'"
SYNTAX OCTET STRING (SIZE (1..63))
MyTimecode ::= TEXTUAL-CONVENTION
DISPLAY-HINT
"11a"
STATUS current
DESCRIPTION
"A display representation for timecode which
essentially provides a machine readable address
for video and audio. Timecodes are represented as
a string of ASCII characters as hh:mm:ss:ff where
hh is hours, mm is minutes, ss is seconds and
ff is video frames."
SYNTAX OCTET STRING (SIZE (0..11))
--
-- The Element MIB top-level groups
--
-- NOTE: { myElementMIB 1 } is reserved for internal use
myGeneral OBJECT IDENTIFIER ::= { myElementMIB 2 }
myTrapTargets OBJECT IDENTIFIER ::= { myElementMIB 3 }
--
-- The Element MIB Object Definitions
--
--
-- The General Group
-- The myGeneral group provides general
-- information for the my managed element.
--
myModel OBJECT-TYPE
SYNTAX DisplayString (SIZE(0..64))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The element model string. The preferred value is
the customer-visible part number, which may be
printed on the physical managed element itself.
If the element being managed does not have
a model descriptor, or the model descriptor is
unknown to the agent, the value of this variable
will be a null string."
::= { myGeneral 1 }
mySerialCode OBJECT-TYPE
SYNTAX DisplayString (SIZE(0..64))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The manufacturing serial code of the
element on which the management software
is running. The preferred value is the serial
number string actually printed on the CCU itself
(if present).
If the element being managed does not have
a serial code, the value of this variable
will be a null string."
::= { myGeneral 2 }
myType OBJECT-TYPE
SYNTAX INTEGER {
myTypeUnknown(1),
-- My Type
myType1(2),
-- My Type
myType2(3),
-- My Type
myType3(4)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Identifies the type of the element being managed."
::= { myGeneral 3 }
mySoftwareRev OBJECT-TYPE
SYNTAX DisplayString (SIZE(0..64))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The revision stamp of the software running on
the element that supports this MIB module."
::= { myGeneral 4 }
myState OBJECT-TYPE
SYNTAX INTEGER {
myElementRunning(1),
myElementInMaintenance(2),
myElementFaulty(3),
myElementDisabled(4),
myElementIdling(5),
myElementInitializing(6),
myElementResetting(7),
myElementHalted(8),
myElementSwLicenseExpired(9),
myElementImntSwLicExpiry(10),
myElementSwLicRecovered(11)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The operational state of an element."
::= { myGeneral 5 }
mySeverityLevel OBJECT-TYPE
SYNTAX INTEGER {
levelUnknown(1),
levelTrace(2),
levelInformational(3),
levelNormal(4),
levelWarning(5),
levelAlarm(6),
levelResentWarning(7),
levelResentAlarm(8)
}
MAX-ACCESS accessible-for-notify
STATUS current
DESCRIPTION
"Defines the typical severity levels"
::= { myGeneral 6 }
myAssetTag OBJECT-TYPE
SYNTAX DisplayString (SIZE(0..64))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"This object is a user-assigned asset tracking identifier for
the element"
::= { myGeneral 7 }
--
-- The Trap Targets Group
-- The myTrapTargets group provides means to
-- configure the trap target specifics using which an
-- element can dispatch traps.
--
myTtMaxTargets OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The maximum number of trap targets that this
element can support.
If the value of this variable is -1, the element
element is capable of supporting a theoretically
infinite number of trap targets dynamically. In
othercases, the maximum number of trap targets
that can be supported by this element is limited
to the value of this variable."
::= { myTrapTargets 1 }
myTtCfgTableNextIndex OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Identifies a hint for the next value of
myTtCfgIndex to be used in a row creation attempt
for the myTtCfgTable table. If no new rows can be
created, this object will have a value of 0."
::= { myTrapTargets 2 }
myTtCfgTable OBJECT-TYPE
SYNTAX SEQUENCE OF MyTtCfgEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"A list of trap target configuration entries on
this element.
Trap Target Configuration Entry Creation:
=========================================
When creating a trap target configuration entry
the manager should use a GET operation to
determine the value of myTtCfgTableNextIndex.0.
If this value is non-zero, the manager can then
use this value as the index while creating a
table row.
The process of creating and activating a row of
this table takes two forms: the one-set mode and
the multiple-set mode.
In the one-set mode, a manager must specify the
values of myTtCfgIpAddress and myTtCfgCommunity
required to activate a row in a single SET operation
along with an assignment of the myTtCfgEntryStatus
to 'createAndGo(4)'. If the values and instances
supplied are correct, an instance of the trap target
configuration is created and the value of
myTtCfgEntryStatus transitions to 'active(1)'.
for example:
============
SnmpGet(<myTtCfgTableNextIndex.0, NULL>)
returns
<myTtCfgTableNextIndex.0, 2>
SnmpSet(<myTtCfgIpAddress.2, 192.158.104.93>,
<myTtCfgCommunity.2, 'public'>,
<myTtCfgEntryStatus.2, createAndGo(4)>)
returns
<myTtCfgIpAddress.2, 192.158.104.93>,
<myTtCfgCommunity.2, 'public'>,
<myTtCfgEntryStatus.2, active(1)>
In the multiple-set mode, creating a trap target
configuration table row, filling it with values,
and activating it are carried out in discrete steps.
To create the row, the manager specifies a value
of 'createAndWait(5)' for the myTtCfgEntryStatus
status variable. This SET request could contain
values of myTtCfgIpAddress and myTtCfgCommunity
but it is not required. More often, the values for
these columnar objects are specified in additional
SET requests. After each SET operation, the
myTtCfgEntryStatus variable takes on the value
'notReady(3)' or 'notInService(2)'. To place the
entry into service, the manager requests that the
myTtCfgEntryStatus variable transition to the
'active(1)' state.
for example:
============
SnmpGet(<myTtCfgTableNextIndex.0>, NULL)
returns
<myTtCfgTableNextIndex.0, 2>
SnmpSet(<myTtCfgEntryStatus.2, createAndWait(5)>)
returns
<myTtCfgEntryStatus.2, notReady(3)>
SnmpSet(<myTtCfgIpAddress.2, 192.158.104.93>,
<myTtCfgCommunity.2, 'public'>)
returns
<myTtCfgIpAddress.2, 192.158.104.93>,
<myTtCfgCommunity.2, 'public'>
SnmpSet(<myTtCfgEntryStatus.2, active(1)>)
returns
<myTtCfgEntryStatus.2, active(1)>
Trap Target Configuration Entry Deletion:
=========================================
To delete an existing trap target configuration
entry, the manager performs a SET operation on the
myTtCfgEntryStatus variable with the value
'destroy(6)'."
::= { myTrapTargets 3 }
myTtCfgEntry OBJECT-TYPE
SYNTAX MyTtCfgEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"A trap target configuration entry."
INDEX { myTtCfgIndex }
::= { myTtCfgTable 1 }
MyTtCfgEntry ::=
SEQUENCE {
myTtCfgIndex
Integer32,
myTtCfgIpAddress
IpAddress,
myTtCfgCommunity
OCTET STRING,
myTtCfgEntryStatus
RowStatus
}
myTtCfgIndex OBJECT-TYPE
SYNTAX Integer32 (1..2147483647)
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"The index of a trap target configuration row.
Note that the value of this object will not
be visible to a manager and any GET/SET
operations on this variable will fail."
::= { myTtCfgEntry 1 }
myTtCfgIpAddress OBJECT-TYPE
SYNTAX IpAddress
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The IP address of the target/manager to which
this element is supposed to send notifications."
::= { myTtCfgEntry 2 }
myTtCfgCommunity OBJECT-TYPE
SYNTAX OCTET STRING (SIZE(0..128))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The community name to be used when this element
sends notifications to the target identified by
this value of this entries myTtCfgIpAddress."
::= { myTtCfgEntry 3 }
myTtCfgEntryStatus OBJECT-TYPE
SYNTAX RowStatus
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"This object controls the creation, activation
and deletion of a row in trap target configuration
table."
::= { myTtCfgEntry 4 }
--
-- The Element MIB Notifications
--
--
-- The notifications group is being assigned the OID "0" so as
-- to comply with the trap handling in the different SNMP versions
--
myMIBNotifications OBJECT IDENTIFIER ::= { myElementMIB 0 }
myStateChange NOTIFICATION-TYPE
OBJECTS {
myState
}
STATUS current
DESCRIPTION
"Notifies when a state change occurs on an element.
The myState variable will hold the new state that
the element is operating in."
::= { myMIBNotifications 1 }
END
snmpget command I used on Manager
snmpget -v 2c -c public 10.16.20.191 MY-ELEMENT-MIB::myModel.0
MY-ELEMENT-MIB::myModel.0 = STRING: Hello World
snmpbulkget command I used on Manager
snmpbulkget -v 2c -c public 10.16.20.191 MY-ELEMENT-MIB::myGeneral
Error in packet.
Reason: (genError) A general failure occured
Failed object: MY-ELEMENT-MIB::myModel.0
Additional Notes:
Using OID directly yields same results
Using Wireshark I see my Linux system response to the getBulkRequest with all the MIBs' info found under the OID
I used -DALL switch in the snmpbulkget command and I see all the MIBs' info found under the OID. Additionally I see Error Status = 5, which explains why I get genError response.
I found my problem. My issue was with the Netsnmp_Node_Handler method I used to register myTtCfgIpAddress OID. I was missing a MODE_GETNEXT & MODE_GETBULK case in CMyMibSubAgent::handle_myTtCfgIpAddress(). Because of this, my switch case defaulted to return SNMP_ERR_GENERR.
Now my recommendation to anyone who comes across this problem, don't solely rely on the SNMP tool response. The snmpbulkget -DALL command told me the problem was with my first OID object (in my case MY-ELEMENT-MIB::myModel.0). However, after using Wireshark, I found that the first few OIDs were returning with valid values, but after it got to my myTtCfgTable, its started having issues. From here I started using snmpgetnext and Wireshark to pinpoint the specific OID that caused the genError. After that, it was just a review of the OID's implementation (and in my case I had to use the debugger to determine the reqinfo->mode I got was MODE_GETNEXT). Hope this explanation helps someone in future.
One more thing, I used Wireshark filter "udp.port==161 || udp.port==162" to only observed SNMP traffic.

javacc C grammar and C "Bit fields" ; ParseException

I'm trying to use this javacc grammar https://java.net/downloads/javacc/contrib/grammars/C.jj to parse a C code containing bit fields
struct T{
int w:2;
};
struct T a;
The generated parser cannot parse this code:
$ javacc -DEBUG_PARSER=true C.jj && javac CParser.java && gcc -E input.c | java CParser
Java Compiler Compiler Version 5.0 (Parser Generator)
(type "javacc" with no arguments for help)
Reading from file C.jj . . .
File "TokenMgrError.java" is being rebuilt.
File "ParseException.java" is being rebuilt.
File "Token.java" is being rebuilt.
File "SimpleCharStream.java" is being rebuilt.
Parser generated successfully.
Note: CParser.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
C Parser Version 0.1Alpha: Reading from standard input . . .
Call: TranslationUnit
Call: ExternalDeclaration
Call: Declaration
Call: DeclarationSpecifiers
Call: TypeSpecifier
Call: StructOrUnionSpecifier
Call: StructOrUnion
Consumed token: <"struct" at line 5 column 1>
Return: StructOrUnion
Consumed token: <<IDENTIFIER>: "T" at line 5 column 8>
Consumed token: <"{" at line 5 column 9>
Call: StructDeclarationList
Call: StructDeclaration
Call: SpecifierQualifierList
Call: TypeSpecifier
Consumed token: <"int" at line 6 column 2>
Return: TypeSpecifier
Return: SpecifierQualifierList
Call: StructDeclaratorList
Call: StructDeclarator
Call: Declarator
Call: DirectDeclarator
Consumed token: <<IDENTIFIER>: "w" at line 6 column 6>
Return: DirectDeclarator
Return: Declarator
Return: StructDeclarator
Return: StructDeclaratorList
Return: StructDeclaration
Return: StructDeclarationList
Return: StructOrUnionSpecifier
Return: TypeSpecifier
Return: DeclarationSpecifiers
Return: Declaration
Return: ExternalDeclaration
Return: TranslationUnit
C Parser Version 0.1Alpha: Encountered errors during parse.
ParseException: Encountered " ":" ": "" at line 6, column 7.
Was expecting one of:
";" ...
"," ...
"(" ...
"[" ...
"[" ...
"(" ...
"(" ...
"," ...
";" ...
";" ...
";" ...
"[" ...
"(" ...
"(" ...
at CParser.generateParseException(CParser.java:4279)
at CParser.jj_consume_token(CParser.java:4154)
at CParser.StructDeclaration(CParser.java:433)
at CParser.StructDeclarationList(CParser.java:372)
at CParser.StructOrUnionSpecifier(CParser.java:328)
at CParser.TypeSpecifier(CParser.java:274)
at CParser.DeclarationSpecifiers(CParser.java:182)
at CParser.Declaration(CParser.java:129)
at CParser.ExternalDeclaration(CParser.java:96)
at CParser.TranslationUnit(CParser.java:77)
at CParser.main(CParser.java:63)
I tried to change (line 245)
(...) LOOKAHEAD( { isType(getToken(1).image) } )TypedefName() )
to
LOOKAHEAD( { isType(getToken(1).image) } ) TypedefName2()
(...)
void TypedefName2() : {}
{
TypedefName() (LOOKAHEAD(2) ":" <INTEGER_LITERAL> )?
}
but it doesn't work (same error) .
Is there a simple way to fix the javaCC grammar to handle Bit Fields ?
Try fixing this by modifying the StructDeclarator() rule on lines 310..313 as follows:
void StructDeclarator() : {}
{
( Declarator() [ ":" ConstantExpression() ] | ":" ConstantExpression() )
}
The idea is to remove the need of lookahead by letting the parser make a decision by checking if the struct declarator starts with a colon ":".

ANTLR3 C Target - parser return 'misses' out root element

I'm trying to use the ANTLR3 C Target to make sense of an AST, but am running into some difficulties.
I have a simple SQL-like grammar file:
grammar sql;
options
{
language = C;
output=AST;
ASTLabelType=pANTLR3_BASE_TREE;
}
sql : VERB fields;
fields : FIELD (',' FIELD)*;
VERB : 'SELECT' | 'UPDATE' | 'INSERT';
FIELD : CHAR+;
fragment
CHAR : 'a'..'z';
and this works as expected within ANTLRWorks.
In my C code I have:
const char pInput[] = "SELECT one,two,three";
pANTLR3_INPUT_STREAM pNewStrm = antlr3NewAsciiStringInPlaceStream((pANTLR3_UINT8) pInput,sizeof(pInput),NULL);
psqlLexer lex = sqlLexerNew (pNewStrm);
pANTLR3_COMMON_TOKEN_STREAM tstream = antlr3CommonTokenStreamSourceNew(ANTLR3_SIZE_HINT,
TOKENSOURCE(lex));
psqlParser ps = sqlParserNew( tstream );
sqlParser_sql_return ret = ps->sql(ps);
pANTLR3_BASE_TREE pTree = ret.tree;
cout << "Tree: " << pTree->toStringTree(pTree)->chars << endl;
ParseSubTree(0,pTree);
This outputs a flat tree structure when you use ->getChildCount and ->children->get to recurse through the tree.
void ParseSubTree(int level,pANTLR3_BASE_TREE pTree)
{
ANTLR3_UINT32 childcount = pTree->getChildCount(pTree);
for (int i=0;i<childcount;i++)
{
pANTLR3_BASE_TREE pChild = (pANTLR3_BASE_TREE) pTree->children->get(pTree->children,i);
for (int j=0;j<level;j++)
{
std::cout << " - ";
}
std::cout <<
pChild->getText(pChild)->chars <<
std::endl;
int f=pChild->getChildCount(pChild);
if (f>0)
{
ParseSubTree(level+1,pChild);
}
}
}
Program output:
Tree: SELECT one , two , three
SELECT
one
,
two
,
three
Now, if I alter the grammar file:
sql : VERB ^fields;
.. the call to ParseSubTree only displays the child nodes of fields.
Program output:
Tree: (SELECT one , two , three)
one
,
two
,
three
My question is: why, in the second case, is Antlr just give the child nodes? (in effect missing out the SELECT token)
I'd be very grateful if anybody can give me any pointers for making sense of the tree returned by Antlr.
Useful Information:
AntlrWorks 1.4.2,
Antlr C Target 3.3,
MSVC 10
Placing output=AST; in the options section will not produce an actual AST, it only causes ANTLR to create CommonTree tokens instead of CommonTokens (or, in your case, the equivalent C structs).
If you use output=AST;, the next step is to put tree operators, or rewrite rules inside your parser rules that give shape to your AST.
See this previous Q&A to find out how to create a proper AST.
For example, the following grammar (with rewrite rules):
options {
output=AST;
// ...
}
sql // make VERB the root
: VERB fields -> ^(VERB fields)
;
fields // omit the comma's from the AST
: FIELD (',' FIELD)* -> FIELD+
;
VERB : 'SELECT' | 'UPDATE' | 'INSERT';
FIELD : CHAR+;
SPACE : ' ' {$channel=HIDDEN;};
fragment CHAR : 'a'..'z';
will parse the following input:
UPDATE field, foo , bar
into the following AST:
I think it is important that you realize that the tree you see in Antrlworks is not the AST. The ".tree" in your code is the AST but may look different from what you expect. In order to create the AST, you need to specify the nodes using the ^ symbol in strategic places using rewrite rules.
You can read more here

Resources