#!/bin/sh # This is `snmp2.33' (part 33 of snmp2). # Do not concatenate these parts, unpack them in order with `/bin/sh'. # File `snmp2/agent/alarm.c' is being continued... # touch -am 1231235999 $$.touch >/dev/null 2>&1 if test ! -f 1231235999 && test -f $$.touch; then shar_touch=touch else shar_touch=: echo echo 'WARNING: not restoring timestamps. Consider getting and' echo "installing GNU \`touch', distributed in GNU File Utilities..." echo fi rm -f 1231235999 $$.touch # if test ! -r _sharseq.tmp; then echo 'Please unpack part 1 first!' exit 1 fi shar_sequence=`cat _sharseq.tmp` if test "$shar_sequence" != 33; then echo "Please unpack part $shar_sequence next!" exit 1 fi if test ! -f _sharnew.tmp; then echo 'x - still skipping snmp2/agent/alarm.c' else echo 'x - continuing file snmp2/agent/alarm.c' sed 's/^X//' << 'SHAR_EOF' >> 'snmp2/agent/alarm.c' && X X if ((index < 1) || (index > 65535)) { X return NULL; X } X X alarm = (struct alarmEntry *)malloc(sizeof(struct alarmEntry)); X while ((alarm == NULL) && (i++ < 5)) { X eventFreeSpace(); X alarm = (struct alarmEntry *)malloc(sizeof(struct alarmEntry)); X } X if (alarm == NULL) { X /* no more room */ X return NULL; X } X X bzero((char *)alarm, sizeof(struct alarmEntry)); X X alarm->index = index; X bcopy(context, alarm->contextID, contextLen * sizeof(oid)); X alarm->contextLength = contextLen; X alarm->status = ENTRY_DESTROY; X X alarm->bitmask = ALARMTABINDEXMASK; X X alarmInsertRow(alarm); X X /* this will copy the index, status, and bitmask into the shadow area */ X if (alarmShadowRow(alarm) == 0) { X /* weren't able to allocate space for the shadow area, so X ** remove the entry from the list. X */ X alarmDeleteRow(alarm); X return NULL; X } X X /* add default entries to the shadow copy. The variables that X ** aren't defaulted are interval, variable, value, startupAlarm, X ** risingThresh, fallingThresh, risingEventIndex, + fallingEventIndex, X */ X alarm->shadow->status = ENTRY_NOTINSERVICE; X alarm->shadow->sampleType = ALARM_DELTA_VALUE; X X alarm->shadow->bitmask |= (ALARMTABSAMPLETYPEMASK | ALARMTABSTATUSMASK); X X alarmNextIndex = random() & 0x0000ffff; X while (alarmGetRowByIndex(alarmNextIndex) != NULL) { X alarmNextIndex = random() & 0x0000ffff; X } X X return alarm; } X /* copy the data in the given row from the shadow copy into the world- ** visible copy, and get rid of the shadow copy. If no shadow copy ** exists, just return. If we are setting the row to invalid, delete it. */ static void alarmCommitRow(alarm) X struct alarmEntry *alarm; { X struct alarmEntry *nextPtr; X u_long destAddr; X X if (alarm->shadow == NULL) { X return; X } X X /* if this entry is being set to invalid, just delete it */ X if (alarm->shadow->status == ENTRY_DESTROY) { X alarmDeleteRow(alarm); X return; X } X X /* if the row will no longer be valid, invalidate the value field */ X if (alarm->status == ENTRY_ACTIVE && X alarm->shadow->status != ENTRY_ACTIVE) { X alarm->shadow->bitmask &= (~ALARMTABVALUEMASK X & ~ALARMTABREALVALUEMASK); X alarm->shadow->value = 0; X } X X /* set up the intervalAdd variable */ X if (alarm->shadow->sampleType == ALARM_ABSOLUTE_VALUE) { X alarm->shadow->intervalAdd.tv_sec = alarm->shadow->interval; X } else { X /* this is a delta value */ X alarm->shadow->intervalAdd.tv_sec = alarm->shadow->interval / 2; X if ((alarm->shadow->interval & 1) == 1) { X /* alarm->shadow->interval is odd; therefore, another half second X ** must be added to its update time X */ X alarm->shadow->intervalAdd.tv_usec = 500000; X } X } X X nextPtr = alarm->next; X bcopy((char *)alarm->shadow, (char *)alarm, sizeof(struct alarmEntry)); X X if (alarm->next != nextPtr) { X /* KLF debugging */ X printf("alarmCommitRow(%d): next pointer was different\n", X alarm->index); X alarm->next = nextPtr; X } X X ((u_char *)&destAddr)[0] = (u_char)alarm->contextID[9]; X ((u_char *)&destAddr)[1] = (u_char)alarm->contextID[10]; X ((u_char *)&destAddr)[2] = (u_char)alarm->contextID[11]; X ((u_char *)&destAddr)[3] = (u_char)alarm->contextID[12]; X X alarm->srcPartyLength X = alarm->dstPartyLength = alarm->contextLength= MAX_NAME_LEN; X ms_party_init(destAddr, alarm->srcPartyID, &(alarm->srcPartyLength), X alarm->dstPartyID, &(alarm->dstPartyLength), X alarm->contextID, &(alarm->contextLength)); #if 0 X bcopy((char *)alarm->contextID, (char *)alarm->srcPartyID, X alarm->contextLength * sizeof(oid)); X bcopy((char *)alarm->contextID, (char *)alarm->dstPartyID, X alarm->contextLength * sizeof(oid)); X alarm->srcPartyLength = alarm->contextLength; X alarm->dstPartyLength = alarm->contextLength; X alarm->srcPartyID[8] = 3; X alarm->dstPartyID[8] = 3; X alarm->srcPartyID[13] = alarm->contextID[13] * 2; X alarm->dstPartyID[13] = (alarm->contextID[13] * 2) - 1; #endif X X alarmFreeShadow(alarm); X X /* note that alarmTimer() will be called within 1/2 second of this X ** entry becoming valid, and will do the startup alarm processing X ** then. This is close enough to "when this entry is first set X ** to valid" for me. X */ } X /* compare the new value against the old one, and send a rising or ** falling alarm if necessary. */ static void alarmProcessValue(alarm, oldValue, newValue) X struct alarmEntry *alarm; X long oldValue; X long newValue; { X if ((alarm->bitmask & ALARMTABVALUEMASK) == 0) { X /* this is the first sample */ X if ((newValue >= alarm->risingThresh) && X ((alarm->startupAlarm == ALARM_STARTUP_RISING) || X (alarm->startupAlarm == ALARM_STARTUP_RISING_OR_FALLING))) { X /* send rising alarm */ X eventGenerate(alarm->risingEventIndex, EVENT_TYPE_STARTUP_RISING, X (void *)alarm); X } X else if ((newValue <= alarm->fallingThresh) && X ((alarm->startupAlarm == ALARM_STARTUP_FALLING) || X (alarm->startupAlarm == ALARM_STARTUP_RISING_OR_FALLING))) { X /* send falling alarm */ X eventGenerate(alarm->fallingEventIndex, EVENT_TYPE_STARTUP_FALLING, X (void *)alarm); X } X } X else if ((newValue >= alarm->risingThresh) && X (oldValue < alarm->risingThresh) && !alarm->cantSendRising) { X /* send rising alarm */ X eventGenerate(alarm->risingEventIndex, EVENT_TYPE_RISING, X (void *)alarm); X alarm->cantSendFalling = FALSE; X alarm->cantSendRising = TRUE; X } X else if ((newValue <= alarm->fallingThresh) && X (oldValue > alarm->fallingThresh) && !alarm->cantSendFalling) { X /* send falling alarm */ X eventGenerate(alarm->fallingEventIndex, EVENT_TYPE_FALLING, X (void *)alarm); X alarm->cantSendRising = FALSE; X alarm->cantSendFalling = TRUE; X } } X /* update a delta counter and send an alarm if necessary */ static void alarmUpdateDelta(alarm, realValue) X struct alarmEntry *alarm; X long realValue; { X long oldValue; X X if ((alarm->bitmask & ALARMTABREALVALUEMASK) == 0) { X /* lastRealValue hasn't been initialized, so do it */ X alarm->lastRealValue = realValue; X alarm->bitmask |= ALARMTABREALVALUEMASK; X alarm->lastDeltaValue = 0; X return; X } X X /* this is the normal case */ X oldValue = alarm->value; X alarm->value = alarm->lastDeltaValue + (realValue - alarm->lastRealValue); X X alarmProcessValue(alarm, oldValue, alarm->value); X X alarm->bitmask |= ALARMTABVALUEMASK; X alarm->lastDeltaValue = realValue - alarm->lastRealValue; X alarm->lastRealValue = realValue; } X /* update an absolute value counter and send an alarm if necessary */ static void alarmUpdateAbs(alarm, value) X struct alarmEntry *alarm; X long value; { X long oldValue; X X oldValue = alarm->value; X alarm->value = value; X X alarmProcessValue(alarm, oldValue, value); X X alarm->bitmask |= ALARMTABVALUEMASK; } X /* search the alarm table for entries whose interval has expired. Record ** the value for the variable and take action if necessary. */ Export void alarmTimer(now) X struct timeval *now; { X struct alarmEntry *alarm; X struct alarmEntry *next; X int error; X long value; X X for (alarm = alarmTab; alarm; alarm = next) { X next = alarm->next; X if (alarm->status == ENTRY_DESTROY) { X alarmDeleteRow(alarm); X continue; X } X X if (alarm->status != ENTRY_ACTIVE) { X /* pretend these don't exist */ X continue; X } X X if (timercmp(now, &alarm->update, <)) { X continue; X } X X error = rmonGetValue(alarm->srcPartyID, alarm->srcPartyLength, X alarm->dstPartyID, alarm->dstPartyLength, X alarm->contextID, alarm->contextLength, X alarm->variable, alarm->variableLen, X &value, alarm); X if (error == 1) { X /* the request was sent out asynchronously. snmp_input() will X ** call one of the alarmUpdate routines. X */ X timeradd(&alarm->update, now, &alarm->intervalAdd); X continue; X } X X if (error) { X /* send objectUnavailable alarm event */ X eventGenerate(alarm->unavailableEventIndex, X EVENT_TYPE_UNAVAILABLE, alarm); X alarmDeleteRow(alarm); X continue; X } X X if (alarm->sampleType == ALARM_DELTA_VALUE) { X alarmUpdateDelta(alarm, value); X } X else { X alarmUpdateAbs(alarm, value); X } X X timeradd(&alarm->update, now, &alarm->intervalAdd); X } } X /* process the response to a Get request */ Export int alarmGetResponse(pdu, state, op, session) X struct snmp_pdu *pdu; X struct get_req_state *state; X int op; X struct snmp_session *session; { X struct alarmEntry *alarm = (struct alarmEntry *)state->info; X struct variable_list *vp; X X if ((alarm->ss != session) || (alarm->reqid != pdu->reqid)) { X return 1; X } X X if (op == TIMED_OUT) { X /* got an error, so send an inform and delete X ** the alarm entry X */ X eventGenerate(alarm->unavailableEventIndex, X EVENT_TYPE_UNAVAILABLE, alarm); X alarm->status = ENTRY_DESTROY; X return 1; X } X X if (pdu->errstat == SNMP_ERR_NOERROR) { X /* send the variable to an update routine */ X vp = pdu->variables; X if (vp && ((vp->type == INTEGER) || (vp->type == COUNTER) || X (vp->type == TIMETICKS) || (vp->type == GAUGE) || X (vp->type == COUNTER64))) { X if (alarm->sampleType == ALARM_DELTA_VALUE) { X alarmUpdateDelta(alarm, *vp->val.integer); X } X else { X alarmUpdateAbs(alarm, *vp->val.integer); X } X } X } X else { X /* got an error, so send an inform and delete X ** the alarm entry X */ X eventGenerate(alarm->unavailableEventIndex, X EVENT_TYPE_UNAVAILABLE, alarm); X alarm->status = ENTRY_DESTROY; X } X return 1; } X /* X * If statP is non-NULL, the referenced object is at that location. X * If statP is NULL and alarm is non-NULL, the instance (row) exists, but not X * this variable. X * If statP is NULL and alarm is NULL, then neither this instance nor the X * variable exists. X */ /* return TRUE on success and FALSE on failure */ static int write_alarmtab(action, var_val, var_val_type, var_val_len, statP, X name, name_len) X int action; /* IN - RESERVE1, RESERVE2, COMMIT, or FREE */ X u_char *var_val; /* IN - input or output buffer space */ X u_char var_val_type; /* IN - type of input buffer */ X int var_val_len; /* IN - input and output buffer len */ X u_char *statP; /* IN - pointer to local statistic */ X oid *name; /* IN - pointer to name requested */ X int name_len; /* IN - number of sub-ids in the name */ { X register int index; X register int variable; X register struct alarmEntry *alarm; X int size; X int int_value; X oid oid_value[MAX_OID_LEN]; X u_char string_value[MAX_OWNER_STR_LEN]; X int buffersize = 1000; X int contextlen; X oid *context; X X /* .1.3.6.1.6.3.2.1.1.2.1.X.cxlen.context.index */ X X contextlen = name[12]; X if (name_len < (13 + contextlen)) X return SNMP_ERR_NOCREATION; X context = name + 13; X index = name[13 + contextlen]; X alarm = alarmGetRow(context, contextlen, index); X X switch (action) { X case RESERVE1: X if (alarm == NULL) { X alarm = alarmNewRow(context, contextlen, index); X if (alarm == NULL) { X /* no memory for row */ X return SNMP_ERR_RESOURCEUNAVAILABLE; X } X } X else { X /* we have a row, but some vars will change. Remember X ** the current numbers. X */ X if (alarmShadowRow(alarm) == 0) { X /* not enough memory available */ X return SNMP_ERR_RESOURCEUNAVAILABLE; X } X } X break; X case RESERVE2: X if (alarm == NULL) { X /* this should have been created in the RESERVE1 phase */ X return SNMP_ERR_GENERR; X } X break; X case COMMIT: X if (alarm == NULL) { X return SNMP_ERR_GENERR; X } X alarmCommitRow(alarm); X return SNMP_ERR_NOERROR; X case FREE: X if (alarm == NULL) { X return SNMP_ERR_GENERR; X } X if (alarm->status == ENTRY_DESTROY) { X /* this row did not exist before we began this RESERVE/FREE X ** cycle, so delete it now. X */ X alarmDeleteRow(alarm); X } X else { X /* the row existed before, so just get rid of the shadow X ** copy. X */ X alarmFreeShadow(alarm); X } X return SNMP_ERR_NOERROR; X } X X variable = name[11]; X X /* interval, variable, sampleType, startupAlarm, risingThresh, X ** fallingThresh, risingEventIndex, fallingEventIndex, X ** and status are the user-writable variables in this table. X */ X switch (variable) { X case ALARMTABVARIABLE: X if (action == RESERVE1) { X /* make sure it's an oid */ X if (var_val_type != ASN_OBJECT_ID) { X return SNMP_ERR_WRONGTYPE; X } X size = sizeof(oid_value) / sizeof(oid); X if (asn_parse_objid(var_val, &buffersize, &var_val_type, X oid_value, &size) == NULL) { X return SNMP_ERR_WRONGENCODING; X } #if 0 X /* this assures that the variable exists and resolves X ** to an integer value X */ X if (rmonGetValue(oid_value, size, (long *)&int_value) != 0) { X return SNMP_ERR_INCONSISTENTVALUE; X } #endif X /* There should also be a check here that the setter X ** can read all variables in the MIB. Since all X ** communities have read access to all variables, X ** this test is punted. X */ X bcopy((char *)oid_value, (char *)alarm->shadow->variable, X size * sizeof(oid)); X alarm->shadow->variableLen = size; X alarm->shadow->bitmask |= ALARMTABVARIABLEMASK; X } X else if (action == RESERVE2) { X /* not allowed to change this if the entry is valid */ X if ((alarm->shadow->status == ENTRY_ACTIVE) && X (alarm->status == ENTRY_ACTIVE)) { X return SNMP_ERR_INCONSISTENTVALUE; X } X } X break; X case ALARMTABINTERVAL: X if (action == RESERVE1) { X if (var_val_type != ASN_INTEGER) { X return SNMP_ERR_WRONGTYPE; X } X if (asn_parse_int(var_val, &buffersize, &var_val_type, X &int_value, sizeof(int_value)) == NULL) { X return SNMP_ERR_WRONGENCODING; X } X alarm->shadow->interval = int_value; X alarm->shadow->bitmask |= ALARMTABINTERVALMASK; X } X else if (action == RESERVE2) { X /* not allowed to change this if the entry is valid */ X if ((alarm->shadow->status == ENTRY_ACTIVE) && X (alarm->status == ENTRY_ACTIVE)) { X return SNMP_ERR_INCONSISTENTVALUE; X } X } X break; X case ALARMTABSAMPLETYPE: X if (action == RESERVE1) { X if (var_val_type != ASN_INTEGER) { X return SNMP_ERR_WRONGTYPE; X } X if (asn_parse_int(var_val, &buffersize, &var_val_type, X &int_value, sizeof(int_value)) == NULL) { X return SNMP_ERR_WRONGENCODING; X } X if ((int_value < ALARM_ABSOLUTE_VALUE) || X (int_value > ALARM_DELTA_VALUE)) { X return SNMP_ERR_WRONGLENGTH; X } X alarm->shadow->sampleType = int_value; X alarm->shadow->bitmask |= ALARMTABSAMPLETYPEMASK; X } X else if (action == RESERVE2) { X /* not allowed to change this if the entry is valid */ X if ((alarm->shadow->status == ENTRY_ACTIVE) && X (alarm->status == ENTRY_ACTIVE)) { X return SNMP_ERR_INCONSISTENTVALUE; X } X } X break; X case ALARMTABSTARTUPALARM: X if (action == RESERVE1) { X if (var_val_type != ASN_INTEGER) { X return SNMP_ERR_WRONGTYPE; X } X if (asn_parse_int(var_val, &buffersize, &var_val_type, X &int_value, sizeof(int_value)) == NULL) { X return SNMP_ERR_WRONGENCODING; X } X if ((int_value < ALARM_STARTUP_RISING) || X (int_value > ALARM_STARTUP_RISING_OR_FALLING)) { X return SNMP_ERR_WRONGVALUE; X } X alarm->shadow->startupAlarm = int_value; X alarm->shadow->bitmask |= ALARMTABSTARTUPALARMMASK; X } X else if (action == RESERVE2) { X /* not allowed to change this if the entry is valid */ X if ((alarm->shadow->status == ENTRY_ACTIVE) && X (alarm->status == ENTRY_ACTIVE)) { X return SNMP_ERR_INCONSISTENTVALUE; X } X } X break; X case ALARMTABRISINGTHRESH: X if (action == RESERVE1) { X if (var_val_type != ASN_INTEGER) { X return SNMP_ERR_WRONGTYPE; X } X if (asn_parse_int(var_val, &buffersize, &var_val_type, X &int_value, sizeof(int_value)) == NULL) { X return SNMP_ERR_WRONGENCODING; X } X alarm->shadow->risingThresh = int_value; X alarm->shadow->bitmask |= ALARMTABRISINGTHRESHMASK; X } X else if (action == RESERVE2) { X /* not allowed to change this if the entry is valid */ X if ((alarm->shadow->status == ENTRY_ACTIVE) && X (alarm->status == ENTRY_ACTIVE)) { X return SNMP_ERR_INCONSISTENTVALUE; X } X } X break; X case ALARMTABFALLINGTHRESH: X if (action == RESERVE1) { X if (var_val_type != ASN_INTEGER) { X return SNMP_ERR_WRONGTYPE; X } X if (asn_parse_int(var_val, &buffersize, &var_val_type, X &int_value, sizeof(int_value)) == NULL) { X return SNMP_ERR_WRONGENCODING; X } X alarm->shadow->fallingThresh = int_value; X alarm->shadow->bitmask |= ALARMTABFALLINGTHRESHMASK; X } X else if (action == RESERVE2) { X /* not allowed to change this if the entry is valid */ X if ((alarm->shadow->status == ENTRY_ACTIVE) && X (alarm->status == ENTRY_ACTIVE)) { X return SNMP_ERR_INCONSISTENTVALUE; X } X } X break; X case ALARMTABRISINGINDEX: X if (action == RESERVE1) { X if (var_val_type != ASN_INTEGER) { X return SNMP_ERR_WRONGTYPE; X } X if (asn_parse_int(var_val, &buffersize, &var_val_type, X &int_value, sizeof(int_value)) == NULL) { X return SNMP_ERR_WRONGENCODING; X } X if ((int_value < 0) || (int_value > 65535)) { X return SNMP_ERR_WRONGVALUE; X } X alarm->shadow->risingEventIndex = int_value; X alarm->shadow->bitmask |= ALARMTABRISINGINDEXMASK; X } X else if (action == RESERVE2) { X /* not allowed to change this if the entry is valid */ X if ((alarm->shadow->status == ENTRY_ACTIVE) && X (alarm->status == ENTRY_ACTIVE)) { X return SNMP_ERR_INCONSISTENTVALUE; X } X } X break; X case ALARMTABFALLINGINDEX: X if (action == RESERVE1) { X if (var_val_type != ASN_INTEGER) { X return SNMP_ERR_WRONGTYPE; X } X if (asn_parse_int(var_val, &buffersize, &var_val_type, X &int_value, sizeof(int_value)) == NULL) { X return SNMP_ERR_WRONGENCODING; X } X if ((int_value < 0) || (int_value > 65535)) { X return SNMP_ERR_WRONGVALUE; X } X alarm->shadow->fallingEventIndex = int_value; X alarm->shadow->bitmask |= ALARMTABFALLINGINDEXMASK; X } X else if (action == RESERVE2) { X /* not allowed to change this if the entry is valid */ X if ((alarm->shadow->status == ENTRY_ACTIVE) && X (alarm->status == ENTRY_ACTIVE)) { X return SNMP_ERR_INCONSISTENTVALUE; X } X } X break; X case ALARMTABUNAVAILABLEINDEX: X if (action == RESERVE1) { X if (var_val_type != ASN_INTEGER) { X return SNMP_ERR_WRONGTYPE; X } X if (asn_parse_int(var_val, &buffersize, &var_val_type, X &int_value, sizeof(int_value)) == NULL) { X return SNMP_ERR_WRONGENCODING; X } X if ((int_value < 0) || (int_value > 65535)) { X return SNMP_ERR_WRONGVALUE; X } X alarm->shadow->unavailableEventIndex = int_value; X alarm->shadow->bitmask |= ALARMTABUNAVAILABLEINDEXMASK; X } X else if (action == RESERVE2) { X /* not allowed to change this if the entry is valid */ X if ((alarm->shadow->status == ENTRY_ACTIVE) && X (alarm->status == ENTRY_ACTIVE)) { X return SNMP_ERR_INCONSISTENTVALUE; X } X } X break; X case ALARMTABSTATUS: X if (action == RESERVE1) { X if (var_val_type != ASN_INTEGER) { X return SNMP_ERR_WRONGTYPE; X } X if (asn_parse_int(var_val, &buffersize, &var_val_type, X &int_value, sizeof(int_value)) == NULL) { X return SNMP_ERR_WRONGENCODING; X } X if (int_value < ENTRY_ACTIVE X || int_value > ENTRY_DESTROY X || int_value == ENTRY_NOTREADY X || int_value == ENTRY_CREATEANDGO) { X return SNMP_ERR_WRONGVALUE; X } X X if (int_value == ENTRY_CREATEANDWAIT) { X if (alarm->status != ENTRY_DESTROY) { X /* this is an entry that already existed; not X ** allowed to set it to underCreation X */ X return SNMP_ERR_INCONSISTENTVALUE; X } X int_value = ENTRY_NOTINSERVICE; X } X X alarm->shadow->status = int_value; X alarm->shadow->bitmask |= ALARMTABSTATUSMASK; X } X else if (action == RESERVE2) { X /* when the entry is first created, the value field is not X ** valid X */ X if ((alarm->shadow->status == ENTRY_ACTIVE) && X (alarm->shadow->bitmask != X (ALARMTABCOMPLETEMASK & ~ALARMTABVALUEMASK))) { X return SNMP_ERR_INCONSISTENTVALUE; X } X } X break; X default: X return SNMP_ERR_GENERR; X } X X return SNMP_ERR_NOERROR; } X Export u_char * var_alarmnextindex(vp, name, length, exact, var_len, write_method) X register struct variable *vp; /* IN - pointer to variable entry that X ** points here X */ X register oid *name; /* IN/OUT - input name requested, X ** output name found X */ X register int *length; /* IN/OUT - length of input and output oid's */ X int exact; /* IN - TRUE if an exact match was requested. */ X int *var_len; /* OUT - length of variable or 0 if function returned. */ X int (**write_method)(); /* OUT - pointer to function to set X ** variable, otherwise 0 X */ { X int result; X X *write_method = NULL; X result = compare(name, *length, vp->name, (int)vp->namelen); X if ((exact && (result != 0)) || (!exact && (result >= 0))) X return NULL; X X bcopy((char *)vp->name, (char *)name, X (int)vp->namelen * sizeof(oid)); X *length = vp->namelen; X *var_len = sizeof(long); X X switch (vp->magic) { X case ALARMNEXTINDEX: X return (u_char *)&alarmNextIndex; X default: X ERROR(""); X } X X return NULL; } X /* respond to requests for variables in the alarm table */ Export u_char * var_alarmtab(vp, name, length, exact, var_len, write_method) X register struct variable *vp; /* IN - pointer to variable entry that X ** points here X */ X register oid *name; /* IN/OUT - input name requested, X ** output name found X */ X register int *length; /* IN/OUT - length of input and output oid's */ X int exact; /* IN - TRUE if an exact match was requested. */ X int *var_len; /* OUT - length of variable or 0 if function returned. */ X int (**write_method)(); /* OUT - pointer to function to set X ** variable, otherwise 0 X */ { X oid newname[MAX_NAME_LEN]; X int result; X int mask; X struct alarmEntry *alarm; X X mask = 1 << (vp->magic - 1); X bcopy((char *)vp->name, (char *)newname, X (int)vp->namelen * sizeof(oid)); X *write_method = write_alarmtab; X X /* .1.3.6.1.6.3.2.1.1.2.1.X.cxlen.context.index */ X X /* find "next" process */ X for (alarm = alarmTab; alarm; alarm = alarm->next) { X if ((alarm->bitmask & mask) == 0) { X /* this variable isn't available for inspection */ X continue; X } X newname[12] = (oid)alarm->contextLength; X bcopy(alarm->contextID, newname + 13, X alarm->contextLength * sizeof(oid)); X newname[13 + alarm->contextLength] = (oid)alarm->index; X result = compare(name, *length, X newname, 14 + alarm->contextLength); X if ((exact && (result == 0)) || (!exact && (result < 0))) X break; X } X if (alarm == NULL) { X return NULL; X } X X X bcopy((char *)newname, (char *)name, X (int)(14 + alarm->contextLength) * sizeof(oid)); X *length = 14 + alarm->contextLength; X *var_len = sizeof(long); X X switch (vp->magic) { X case ALARMTABVARIABLE: X *var_len = alarm->variableLen * sizeof(oid); X return (u_char *)alarm->variable; X case ALARMTABINTERVAL: X return (u_char *)&alarm->interval; X case ALARMTABSAMPLETYPE: X return (u_char *)&alarm->sampleType; X case ALARMTABVALUE: X *write_method = NULL; X return (u_char *)&alarm->value; X case ALARMTABSTARTUPALARM: X return (u_char *)&alarm->startupAlarm; X case ALARMTABRISINGTHRESH: X return (u_char *)&alarm->risingThresh; X case ALARMTABFALLINGTHRESH: X return (u_char *)&alarm->fallingThresh; X case ALARMTABRISINGINDEX: X return (u_char *)&alarm->risingEventIndex; X case ALARMTABFALLINGINDEX: X return (u_char *)&alarm->fallingEventIndex; X case ALARMTABUNAVAILABLEINDEX: X return (u_char *)&alarm->fallingEventIndex; X case ALARMTABSTATUS: X if (alarm->status == ENTRY_NOTINSERVICE){ X if (alarm->bitmask != X (ALARMTABCOMPLETEMASK & ~ALARMTABVALUEMASK)){ X long_return = ENTRY_NOTREADY; X return (u_char *)&long_return; X } X } X return (u_char *)&alarm->status; X default: X ERROR(""); X } X X return NULL; } SHAR_EOF echo 'File snmp2/agent/alarm.c is complete' && $shar_touch -am 1015123693 'snmp2/agent/alarm.c' && chmod 0644 'snmp2/agent/alarm.c' || echo 'restore of snmp2/agent/alarm.c failed' shar_count="`wc -c < 'snmp2/agent/alarm.c'`" test 34090 -eq "$shar_count" || echo "snmp2/agent/alarm.c: original size 34090, current size $shar_count" rm -f _sharnew.tmp fi # ============= snmp2/agent/alarm.h ============== if test -f 'snmp2/agent/alarm.h' && test X"$1" != X"-c"; then echo 'x - skipping snmp2/agent/alarm.h (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting snmp2/agent/alarm.h (text)' sed 's/^X//' << 'SHAR_EOF' > 'snmp2/agent/alarm.h' && /* include file for alarm module */ X extern u_char *var_alarmtab(); extern u_char *var_alarmnextindex(); extern void alarmTimer(); X /* defines for values of alarmEntry.sampleType */ #define ALARM_ABSOLUTE_VALUE 1 #define ALARM_DELTA_VALUE 2 X /* defines for values of alarmEntry.startupAlarm */ #define ALARM_STARTUP_RISING 1 #define ALARM_STARTUP_FALLING 2 #define ALARM_STARTUP_RISING_OR_FALLING 3 X struct alarmEntry { X struct alarmEntry *next; X int index; /* 1..65535 */ X oid dstPartyID[MAX_OID_LEN]; X int dstPartyLength; X oid srcPartyID[MAX_OID_LEN]; X int srcPartyLength; X oid contextID[MAX_OID_LEN]; X int contextLength; X long interval; X oid variable[MAX_OID_LEN]; X int variableLen; /* number of subids in "variable" */ X int sampleType; X long value; X int startupAlarm; X long risingThresh; X long fallingThresh; X int risingEventIndex; /* same as an eventIndex */ X int fallingEventIndex; /* same as an eventIndex */ X int unavailableEventIndex; /* same as an eventIndex */ X char owner[MAX_OWNER_STR_LEN]; X int status; X struct timeval update; /* time that next update should occur */ X struct timeval intervalAdd; /* amount to add to get to next update */ X char cantSendRising; /* boolean: may a rising event be sent? */ X char cantSendFalling; /* boolean: may a falling event be sent? */ X char cantSendUnavailable; /* boolean: may an unavailable event be sent? */ X long lastRealValue; /* used for delta samples */ X long lastDeltaValue; /* used for delta samples */ X struct snmp_session *ss; X int reqid; X struct get_req_state *magic; /* for snmp api */ X struct alarmEntry *shadow; /* copy for row creates and changes */ X u_long bitmask; /* mask of valid variables */ }; X /* masks for the bitmask field in struct alarmEntry */ #define ALARMTABINDEXMASK 0x00000001 #define ALARMTABVARIABLEMASK 0x00000002 #define ALARMTABINTERVALMASK 0x00000004 #define ALARMTABSAMPLETYPEMASK 0x00000008 #define ALARMTABVALUEMASK 0x00000010 #define ALARMTABSTARTUPALARMMASK 0x00000020 #define ALARMTABRISINGTHRESHMASK 0x00000040 #define ALARMTABFALLINGTHRESHMASK 0x00000080 #define ALARMTABRISINGINDEXMASK 0x00000100 #define ALARMTABFALLINGINDEXMASK 0x00000200 #define ALARMTABUNAVAILABLEINDEXMASK 0x00000400 #define ALARMTABSTATUSMASK 0x00000800 X #define ALARMTABCOMPLETEMASK 0x00000FFF X /* this define has nothing to do with the protocol, just the ** implementation. It's here because it's convenient. */ #define ALARMTABREALVALUEMASK 0x10000000 SHAR_EOF $shar_touch -am 1015123693 'snmp2/agent/alarm.h' && chmod 0644 'snmp2/agent/alarm.h' || echo 'restore of snmp2/agent/alarm.h failed' shar_count="`wc -c < 'snmp2/agent/alarm.h'`" test 2557 -eq "$shar_count" || echo "snmp2/agent/alarm.h: original size 2557, current size $shar_count" rm -f _sharnew.tmp fi # ============= snmp2/agent/context_vars.c ============== if test -f 'snmp2/agent/context_vars.c' && test X"$1" != X"-c"; then echo 'x - skipping snmp2/agent/context_vars.c (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting snmp2/agent/context_vars.c (text)' sed 's/^X//' << 'SHAR_EOF' > 'snmp2/agent/context_vars.c' && #ifdef VXWORKS #include "VXtypes.h" #include "VXtime.h" #else #include #include #endif X #include "asn1.h" #include "snmp.h" #include "snmp_impl.h" #include "snmp_vars.h" #include "system.h" X #include "context.h" #include "acl.h" #include "view.h" X static oid currentTime[] = {1, 3, 6, 1, 6, 3, 3, 1, 2, 1}; static oid restartTime[] = {1, 3, 6, 1, 6, 3, 3, 1, 2, 2}; static oid cacheTime[] = {1, 3, 6, 1, 6, 3, 3, 1, 2, 3}; X #define OIDCMP(l1, l2, o1, o2) (((l1) == (l2)) \ X && !bcmp((char *)(o1), (char *)(o2), \ X (l1)*sizeof(oid))) X #define CONTEXTIDENTITY_MASK 0x0001 #define CONTEXTINDEX_MASK 0x0002 #define CONTEXTVIEWINDEX_MASK 0x0004 #define CONTEXTLOCALENTITY_MASK 0x0008 #define CONTEXTLOCALTIME_MASK 0x0010 #define CONTEXTDSTPARTYINDEX_MASK 0x0020 #define CONTEXTSRCPARTYINDEX_MASK 0x0040 #define CONTEXTPROXYCONTEXT_MASK 0x0080 #define CONTEXTSTORAGETYPE_MASK 0x0100 #define CONTEXTSTATUS_MASK 0x0200 X #define CONTEXTCOMPLETE_MASK 0x03FF /* all collumns */ X struct contextEntry * context_rowCreate(contextID, contextIDLen) X oid *contextID; X int contextIDLen; { X struct contextEntry *cp; X X if (contextIDLen > 32) X return NULL; X cp = context_createEntry(contextID, contextIDLen); X cp->contextBitMask = 0; X cp->contextStatus = cp->reserved->contextStatus = CONTEXTNONEXISTENT; X X cp->contextBitMask = cp->reserved->contextBitMask = X CONTEXTINDEX_MASK | CONTEXTSTATUS_MASK; X /* Watch out for this becoming permanent by accident: X * If during FREE stage below we discover row didn't exist before, X * free row. X */ X return cp; } X context_rowDelete(contextID, contextIDLen) X oid *contextID; X int contextIDLen; { X context_destroyEntry(contextID, contextIDLen); } X /* X * If statP is non-NULL, the referenced object is at that location. X * If statP is NULL and cp is non-NULL, the instance exists, but not this X * variable. X * If statP is NULL and cp is NULL, then neither this instance nor the X * variable exists. X */ int write_context(action, var_val, var_val_type, var_val_len, statP, name, length) X int action; X u_char *var_val; X u_char var_val_type; X int var_val_len; X u_char *statP; X oid *name; X int length; { X struct contextEntry *cp, *rp; X int var, indexlen, len; X oid *index; X long val; X oid buf[32]; X int bigsize = 1000, size; X struct aclEntry *ap; X struct viewEntry *vp; X u_long get_myaddr(), myaddr; X #if 0 X if (length < 13) /* maybe this should be 15 to guarantee oidlength >= 2 */ X return SNMP_ERR_NOCREATION; X var = name[11]; X indexlen = name[12]; X index = name + 13; X if (length != 13 + indexlen) X return SNMP_ERR_NOCREATION; X X cp = context_getEntry(index, indexlen); X if (cp) X rp = cp->reserved; X if (action == RESERVE1 && !cp){ X if ((cp = context_rowCreate(index, indexlen)) == NULL) X return SNMP_ERR_RESOURCEUNAVAILABLE; X rp = cp->reserved; X /* create default vals here in reserve area X * contextIndex is automatically defval'd by context_createEntry(). X */ X rp->contextTDomain = DOMAINSNMPUDP; X bzero((char *)rp->contextTAddress, 6); X rp->contextTAddressLen = 6; X rp->contextMaxMessageSize = 484; X rp->contextLocal = 2; /* FALSE */ X rp->contextAuthProtocol = NOAUTH; X rp->contextAuthClock = 0; X rp->contextAuthPrivateLen = 0; X rp->contextAuthPublicLen = 0; X rp->contextAuthLifetime = 300; X rp->contextPrivProtocol = NOPRIV; X rp->contextPrivPrivateLen = 0; X rp->contextPrivPublicLen = 0; X rp->contextStorageType = 2; /* volatile */ X rp->contextStatus = CONTEXTACTIVE; X rp->contextBitMask = CONTEXTCOMPLETE_MASK ^ CONTEXTLOCAL_MASK; /* XXX */ X } else if (action == COMMIT){ X if (cp->contextStatus == CONTEXTNONEXISTENT){ X /* commit the default vals */ X /* This hacpens at most once per entry because the status is set to X valid after the first pass. After that, this commit code X does not get executed. It is also important to note that this X gets executed before any of the commits below (and never after X them), so they overlay their data on top of these defaults. X This commit code should allow for the object specific code X to have overlayed data after the code above has executed. X */ X cp->contextTDomain = rp->contextTDomain; X bcopy(rp->contextTAddress, cp->contextTAddress, rp->contextTAddressLen); X cp->contextTAddressLen = rp->contextTAddressLen; X cp->contextMaxMessageSize = rp->contextMaxMessageSize; X cp->contextLocal = rp->contextLocal; X cp->contextAuthProtocol = rp->contextAuthProtocol; X cp->contextAuthClock = rp->contextAuthClock; X gettimeofday(&cp->tv, (struct timezone *)0); X cp->tv.tv_sec -= cp->contextAuthClock; X cp->contextAuthPrivateLen = rp->contextAuthPrivateLen; X cp->contextAuthPublicLen = rp->contextAuthPublicLen; X cp->contextAuthLifetime = rp->contextAuthLifetime; X cp->contextPrivProtocol = rp->contextPrivProtocol; X cp->contextPrivPrivateLen = rp->contextPrivPrivateLen; X cp->contextPrivPublicLen = rp->contextPrivPublicLen; X cp->contextStorageType = rp->contextStorageType; X cp->contextStatus = rp->contextStatus; X cp->contextBitMask = rp->contextBitMask; X X } X } else if (action == FREE){ X if (cp && cp->contextStatus == CONTEXTNONEXISTENT){ X context_rowDelete(index, indexlen); X cp = rp = NULL; X } X if (cp) /* satisfy postcondition for bitMask */ X rp->contextBitMask = cp->contextBitMask; X } X /* XXX !!! check return values from the asn_parse_* routines */ X switch(var){ X case CONTEXTTDOMAIN: X if (action == RESERVE1){ X if (var_val_type != ASN_OBJECT_ID) X return SNMP_ERR_WRONGTYPE; X size = sizeof(buf)/sizeof(oid); X asn_parse_objid(var_val, &bigsize, &var_val_type, buf, &size); X if (OIDCMP(size, sizeof(snmpUdpDomain)/sizeof(oid), buf, X snmpUdpDomain)){ X rp->contextTDomain = DOMAINSNMPUDP; X rp->contextBitMask |= CONTEXTTDOMAIN_MASK; X } else { X return SNMP_ERR_WRONGVALUE; X } X } else if (action == COMMIT){ X cp->contextTDomain = rp->contextTDomain; X } X break; X case CONTEXTTADDRESS: X if (action == RESERVE1){ X if (var_val_type != ASN_OCTET_STR) X return SNMP_ERR_WRONGTYPE; X size = sizeof(rp->contextTAddress); X asn_parse_string(var_val, &bigsize, &var_val_type, X rp->contextTAddress, &size); X rp->contextTAddressLen = size; X /* if other TDomains were possible, it would be necessary to X check the size in the reserve2 phase to see if it was X consistent with the TDomain. X Also: what if TAddr is changed to a local context: consider X implications for MaxMessageSize. X */ X if (size != 6) X return SNMP_ERR_WRONGLENGTH; X rp->contextBitMask |= CONTEXTTADDRESS_MASK; X } else if (action == COMMIT){ X cp->contextTAddressLen = rp->contextTAddressLen; X bcopy(rp->contextTAddress, cp->contextTAddress, cp->contextTAddressLen); X } X break; X case CONTEXTMAXMESSAGESIZE: X if (action == RESERVE1){ X if (var_val_type != ASN_INTEGER) X return SNMP_ERR_WRONGTYPE; X asn_parse_int(var_val, &bigsize, &var_val_type, &val, sizeof(val)); X if (val < 484 || val > 65507) X return SNMP_ERR_WRONGVALUE; X rp->contextMaxMessageSize = val; X rp->contextBitMask |= CONTEXTMAXMESSAGESIZE_MASK; X } else if (action == RESERVE2){ X myaddr = get_myaddr(); X if ((rp->contextTDomain == DOMAINSNMPUDP) X && !bcmp((char *)&myaddr, rp->contextTAddress, 4)){ X /* context is local */ X /* 1500 should be constant in snmp_impl.h */ X if (rp->contextMaxMessageSize > 1500) X return SNMP_ERR_INCONSISTENTVALUE; X } X } else if (action == COMMIT){ X cp->contextMaxMessageSize = rp->contextMaxMessageSize; X } X break; X case CONTEXTLOCAL: X if (action == RESERVE1){ X if (var_val_type != ASN_INTEGER) X return SNMP_ERR_WRONGTYPE; X asn_parse_int(var_val, &bigsize, &var_val_type, &val, sizeof(val)); X if (val < 1 || val > 2) X return SNMP_ERR_WRONGVALUE; X rp->contextLocal = val; X rp->contextBitMask |= CONTEXTLOCAL_MASK; X } else if (action == RESERVE2){ X myaddr = get_myaddr(); X if (val == 1 && (rp->contextTDomain == DOMAINSNMPUDP) X && bcmp((char *)&myaddr, rp->contextTAddress, 4)){ X /* this is an attempt to set this context local with a X remote IP address */ X return SNMP_ERR_INCONSISTENTVALUE; X } X } else if (action == COMMIT){ X cp->contextLocal = rp->contextLocal; X } X break; X case CONTEXTAUTHPROTOCOL: X if (action == RESERVE1){ X if (var_val_type != ASN_OBJECT_ID) X return SNMP_ERR_WRONGTYPE; X size = sizeof(buf)/sizeof(oid); X asn_parse_objid(var_val, &bigsize, &var_val_type, buf, &size); X if (OIDCMP(size, sizeof(noAuth)/sizeof(oid), buf, noAuth)){ X rp->contextAuthProtocol = NOAUTH; X } else if (OIDCMP(size, sizeof(snmpv2MD5AuthProt)/sizeof(oid), buf, X snmpv2MD5AuthProt)){ X rp->contextAuthProtocol = SNMPV2MD5AUTHPROT; X } else { X /* no other currently defined */ X return SNMP_ERR_WRONGVALUE ; X } X rp->contextBitMask |= CONTEXTAUTHPROTOCOL_MASK; X } else if (action == COMMIT){ X cp->contextAuthProtocol = rp->contextAuthProtocol; X } X break; X case CONTEXTAUTHCLOCK: X if (action == RESERVE1){ X if (var_val_type != ASN_INTEGER) X return SNMP_ERR_WRONGTYPE; X asn_parse_int(var_val, &bigsize, &var_val_type, &val, sizeof(val)); X rp->contextAuthClock = val; X rp->contextBitMask |= CONTEXTAUTHCLOCK_MASK; X } else if (action == COMMIT){ X cp->contextAuthClock = rp->contextAuthClock; X gettimeofday(&cp->tv, (struct timezone *)0); X cp->tv.tv_sec -= cp->contextAuthClock; X } X break; X case CONTEXTAUTHPRIVATE: X if (action == RESERVE1){ X if (var_val_type != ASN_OCTET_STR) X return SNMP_ERR_WRONGTYPE; X size = sizeof(rp->contextAuthPrivate); X asn_parse_string(var_val, &bigsize, &var_val_type, X rp->contextAuthPrivate, &size); X rp->contextAuthPrivateLen = size; X if (size > 16) X return SNMP_ERR_WRONGLENGTH; X rp->contextBitMask |= CONTEXTAUTHPRIVATE_MASK; X } else if (action == COMMIT){ X if (!(cp->contextBitMask & CONTEXTAUTHPRIVATE_MASK)) X cp->contextAuthPrivateLen = 0; X for(len = 0; (len < cp->contextAuthPrivateLen) X && (len < rp->contextAuthPrivateLen); len++){ X cp->contextAuthPrivate[len] ^= X rp->contextAuthPrivate[len]; X } X while(len < rp->contextAuthPrivateLen) X cp->contextAuthPrivate[len] = X rp->contextAuthPrivate[len]; X cp->contextAuthPrivateLen = rp->contextAuthPrivateLen; X } X break; X case CONTEXTAUTHPUBLIC: X if (action == RESERVE1){ X if (var_val_type != ASN_OCTET_STR) X return SNMP_ERR_WRONGTYPE; X size = sizeof(rp->contextAuthPublic); X asn_parse_string(var_val, &bigsize, &var_val_type, X rp->contextAuthPublic, &size); X rp->contextAuthPublicLen = size; X if (size > 32) X return SNMP_ERR_WRONGLENGTH; X rp->contextBitMask |= CONTEXTAUTHPUBLIC_MASK; X } else if (action == COMMIT){ X cp->contextAuthPublicLen = rp->contextAuthPublicLen; X bcopy((char *)rp->contextAuthPublic, X (char *)cp->contextAuthPublic, cp->contextAuthPublicLen); X } X break; X case CONTEXTAUTHLIFETIME: X if (action == RESERVE1){ X if (var_val_type != ASN_INTEGER) X return SNMP_ERR_WRONGTYPE; X asn_parse_int(var_val, &bigsize, &var_val_type, &val, sizeof(val)); X /* what range should I check for ??? X if (val < 1 || val > 3600) X return SNMP_ERR_WRONGVALUE; X */ X rp->contextAuthLifetime = val; X rp->contextBitMask |= CONTEXTAUTHLIFETIME_MASK; X } else if (action == COMMIT){ X cp->contextAuthLifetime = rp->contextAuthLifetime; X } X break; X case CONTEXTPRIVPROTOCOL: X if (action == RESERVE1){ X if (var_val_type != ASN_OBJECT_ID) X return SNMP_ERR_WRONGTYPE; X size = sizeof(buf)/sizeof(oid); X asn_parse_objid(var_val, &bigsize, &var_val_type, buf, &size); X if (OIDCMP(size, sizeof(noPriv)/sizeof(oid), buf, noPriv)){ X rp->contextPrivProtocol = NOPRIV; X } else if (OIDCMP(size, sizeof(dESPrivProt)/sizeof(oid), buf, X dESPrivProt)){ X rp->contextPrivProtocol = DESPRIVPROT; X } else { X /* no other currently defined */ X return SNMP_ERR_WRONGVALUE; X } X rp->contextBitMask |= CONTEXTPRIVPROTOCOL_MASK; X } else if (action == COMMIT){ X cp->contextPrivProtocol = rp->contextPrivProtocol; X } X break; X case CONTEXTPRIVPRIVATE: X if (action == RESERVE1){ X if (var_val_type != ASN_OCTET_STR) X return SNMP_ERR_WRONGTYPE; X size = sizeof(rp->contextPrivPrivate); X asn_parse_string(var_val, &bigsize, &var_val_type, X rp->contextPrivPrivate, &size); X rp->contextPrivPrivateLen = size; X if (size > 16) X return SNMP_ERR_WRONGLENGTH; X rp->contextBitMask |= CONTEXTPRIVPRIVATE_MASK; X } else if (action == COMMIT){ X if (!(cp->contextBitMask & CONTEXTPRIVPRIVATE_MASK)) X cp->contextPrivPrivateLen = 0; X for(len = 0; (len < cp->contextPrivPrivateLen) X && (len < rp->contextPrivPrivateLen); len++){ X cp->contextPrivPrivate[len] ^= X rp->contextPrivPrivate[len]; X } X while(len < rp->contextPrivPrivateLen) X cp->contextPrivPrivate[len] = X rp->contextPrivPrivate[len]; X cp->contextPrivPrivateLen = rp->contextPrivPrivateLen; X } X break; X case CONTEXTPRIVPUBLIC: X if (action == RESERVE1){ X if (var_val_type != ASN_OCTET_STR) X return SNMP_ERR_WRONGTYPE; X size = sizeof(rp->contextPrivPublic); X asn_parse_string(var_val, &bigsize, &var_val_type, X rp->contextPrivPublic, &size); X rp->contextPrivPublicLen = size; X if (size > 32) X return SNMP_ERR_WRONGLENGTH; X rp->contextBitMask |= CONTEXTPRIVPUBLIC_MASK; X } else if (action == COMMIT){ X bcopy((char *)rp->contextPrivPublic, (char *)cp->contextPrivPublic, X rp->contextPrivPublicLen); X cp->contextPrivPublicLen = rp->contextPrivPublicLen; X } X break; X case CONTEXTSTORAGETYPE: X if (action == RESERVE1){ X if (var_val_type != ASN_INTEGER) X return SNMP_ERR_WRONGTYPE; X asn_parse_int(var_val, &bigsize, &var_val_type, &val, sizeof(val)); X if (val < 1 || val > 4) X return SNMP_ERR_WRONGVALUE; X if (val != 2) /* above is as per MIB, X this is implementation specific */ X return SNMP_ERR_WRONGVALUE; X rp->contextStorageType = val; X rp->contextBitMask |= CONTEXTSTORAGETYPE_MASK; X } else if (action == COMMIT){ X cp->contextStorageType = rp->contextStorageType; X } X break; X case CONTEXTSTATUS: /* read-write access */ X if (action == RESERVE1){ X if (var_val_type != ASN_INTEGER) X return SNMP_ERR_WRONGTYPE; X asn_parse_int(var_val, &bigsize, &var_val_type, &val, sizeof(val)); X if (val < 1 || val > 6 || val == 3) X return SNMP_ERR_WRONGVALUE; X rp->contextStatus = val; X rp->contextBitMask |= CONTEXTSTATUS_MASK; X } else if (action == RESERVE2){ X if (((rp->contextStatus == CONTEXTCREATEANDGO) X || (rp->contextStatus == CONTEXTCREATEANDWAIT)) X && (cp->contextStatus != CONTEXTNONEXISTENT)) X return SNMP_ERR_INCONSISTENTVALUE; X if (((rp->contextStatus == CONTEXTACTIVE) X || (rp->contextStatus == CONTEXTNOTINSERVICE)) X && (cp->contextStatus == CONTEXTNONEXISTENT)) X return SNMP_ERR_INCONSISTENTVALUE; X if (((rp->contextStatus == CONTEXTACTIVE) X || (rp->contextStatus == CONTEXTNOTINSERVICE)) X && (rp->contextBitMask != CONTEXTCOMPLETE_MASK)) X return SNMP_ERR_INCONSISTENTVALUE; X /* tried to set incomplete row valid */ X } else if (action == COMMIT){ X if (rp->contextStatus == CONTEXTCREATEANDGO) X rp->contextStatus = CONTEXTACTIVE; X if (rp->contextStatus == CONTEXTCREATEANDWAIT) X rp->contextStatus = CONTEXTNOTINSERVICE; X cp->contextStatus = rp->contextStatus; X } else if (action == ACTION && cp->contextStatus == CONTEXTDESTROY){ X /* delete all related acl entries */ X acl_scanInit(); X ap = acl_scanNext(); X do { X for(; ap; ap = acl_scanNext()){ X if ((ap->aclTargetLen == cp->contextIdentityLen X && !bcmp(ap->aclTarget, cp->contextIdentity, X ap->aclTargetLen * sizeof(oid))) X || (ap->aclSubjectLen == cp->contextIdentityLen X && !bcmp(ap->aclSubject, cp->contextIdentity, X ap->aclSubjectLen * sizeof(oid)))){ X acl_destroyEntry(ap->aclTarget, ap->aclTargetLen, X ap->aclSubject, ap->aclSubjectLen); X acl_scanInit(); X ap = acl_scanNext(); X break; X /* ap is still set, so we'll start over again */ X } X } X } while (ap); X X /* delete all related view entries */ X view_scanInit(); X vp = view_scanNext(); X do { X for(; vp; vp = view_scanNext()){ X if (vp->viewContextLen == cp->contextIdentityLen X && !bcmp(vp->viewContext, cp->contextIdentity, X vp->viewContextLen * sizeof(oid))){ X view_destroyEntry(vp->viewContext, vp->viewContextLen, X vp->viewSubtree, vp->viewSubtreeLen); X view_scanInit(); X vp = view_scanNext(); X break; X /* vp is still set, so we'll start over again */ X } X } X } while (vp); X X /* then delete the context itself */ X context_rowDelete(cp->contextIdentity, cp->contextIdentityLen); X } X /* if action and context created and it is local, open up new X * listening port, if acpropriate. X */ X break; X case CONTEXTIDENTITY: X default: X return SNMP_ERR_NOCREATION; X } X if (action == COMMIT) /* make any new collumns acpear */ X cp->contextBitMask = rp->contextBitMask; X #endif X return SNMP_ERR_NOERROR; } X u_char * var_context(vp, name, length, exact, var_len, write_method) X register struct variable *vp; /* IN - pointer to variable entry that points here */ X register oid *name; /* IN/OUT - input name requested, output name found */ X register int *length; /* IN/OUT - length of input and output oid's */ X int exact; /* IN - TRUE if an exact match was requested. */ X int *var_len; /* OUT - length of variable or 0 if function returned. */ X int (**write_method)(); /* OUT - pointer to function to set variable, otherwise 0 */ { X oid newname[MAX_NAME_LEN], lowname[MAX_NAME_LEN]; X int newnamelen, lownamelen; SHAR_EOF : || echo 'restore of snmp2/agent/context_vars.c failed' fi echo 'End of snmp2 part 33' echo 'File snmp2/agent/context_vars.c is continued in part 34' echo 34 > _sharseq.tmp exit 0