[PHP-DEV] SNMPset From: Roderick Groesbeek (rgroesb <email protected>)
Date: 02/28/99

        
                Good(morning|day|evening),

Contents:
---------
- Info
- Trailer
- Diff

Info:
-----
I have just started to program in PHP. [It's very nice, it's what I should
have been missing in apache all along. But I guess you all already knew :-]
I missed a SNMPset() function, and I needed it very badly.
So I have extended snmp.c with a snmpset() function.
I would really like to see it distributed in the future PHP releases.
Rasmus gave me the advice to post the diff -c here, so here she comes.

Kind Regards,

Roderick

---
Alkmaar Linux Promoter

################# BEGIN AUTOMATED FORTUNE MESSAGE ################### MCSE: Must Consult Someone Experienced ################# END AUTOMATED FORTUNE MESSAGE ###################

Diff: ----- [BEGIN diff]

*** php/cvs/functions/snmp.c Sun Feb 21 18:09:09 1999 --- php/php-3.0.6/functions/snmp.c Mon Mar 1 00:57:14 1999 *************** *** 2,8 **** +----------------------------------------------------------------------+ | PHP HTML Embedded Scripting Language Version 3.0 | +----------------------------------------------------------------------+ ! | Copyright (c) 1997-1999 PHP Development Team (See Credits file) | +----------------------------------------------------------------------+ | This program is free software; you can redistribute it and/or modify | | it under the terms of one of the following licenses: | --- 2,8 ---- +----------------------------------------------------------------------+ | PHP HTML Embedded Scripting Language Version 3.0 | +----------------------------------------------------------------------+ ! | Copyright (c) 1997,1998 PHP Development Team (See Credits file) | +----------------------------------------------------------------------+ | This program is free software; you can redistribute it and/or modify | | it under the terms of one of the following licenses: | *************** *** 26,32 **** | Authors: Rasmus Lerdorf <rasmus <email protected>> | +----------------------------------------------------------------------+ */ ! /* $Id: snmp.c,v 1.9 1999/01/05 16:12:28 martin Exp $ */ #include "php.h" #include "internal_functions.h" --- 26,32 ---- | Authors: Rasmus Lerdorf <rasmus <email protected>> | +----------------------------------------------------------------------+ */ ! /* $Id: snmp.c,v 1.7 1998/11/15 07:45:19 jah Exp $ */ #include "php.h" #include "internal_functions.h" *************** *** 45,55 **** #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> - #ifndef _OSD_POSIX #include <sys/errno.h> - #else - #include <errno.h> /* BS2000/OSD uses <errno.h>, not <sys/errno.h> */ - #endif #include <netdb.h> #endif #ifdef HAVE_UNISTD_H --- 45,51 ---- *************** *** 90,95 **** --- 86,92 ---- function_entry snmp_functions[] = { {"snmpget", php3_snmpget, NULL}, {"snmpwalk", php3_snmpwalk, NULL}, + {"snmpset", php3_snmpset, NULL}, {NULL,NULL,NULL} }; *************** *** 183,188 **** --- 180,186 ---- php3_error(E_WARNING,"Couldn't open snmp\n"); RETURN_FALSE; } + if (st==2) { memmove((char *)name, (char *)root, rootlen * sizeof(oid)); name_length = rootlen; *************** *** 198,204 **** if (st==1) { name_length = MAX_NAME_LEN; if (!read_objid(objid, name, &name_length)) { ! php3_error(E_WARNING,"Invalid object identifier: %s\n", objid); RETURN_FALSE; } } --- 196,207 ---- if (st==1) { name_length = MAX_NAME_LEN; if (!read_objid(objid, name, &name_length)) { ! php3_error(E_WARNING,"Invalid object identifier: %s\n", objid); ! /* [Unk] Fix me! ! Why don't we call 'snmp_close()' here?? ! Even so, at the other "RETURN_FALSE" ! locations. ! */ RETURN_FALSE; } } *************** *** 213,221 **** continue; /* not part of this subtree */ sprint_value(buf,vars->name, vars->name_length, vars); ! #if 0 Debug("snmp response is: %s\n",buf); ! #endif if (st==1) { RETVAL_STRING(buf,1); } else if (st==2) { --- 216,224 ---- continue; /* not part of this subtree */ sprint_value(buf,vars->name, vars->name_length, vars); ! #if 0 Debug("snmp response is: %s\n",buf); ! #endif if (st==1) { RETVAL_STRING(buf,1); } else if (st==2) { *************** *** 226,232 **** name_length = vars->name_length; keepwalking = 1; } ! } } } else { if (st!=2 || response->errstat != SNMP_ERR_NOSUCHNAME) { --- 229,235 ---- name_length = vars->name_length; keepwalking = 1; } ! } } } else { if (st!=2 || response->errstat != SNMP_ERR_NOSUCHNAME) { *************** *** 271,281 **** --- 274,582 ---- } /* }}} */ + + + /*************************************************************************** + 23-02-1999 + [Unk] rgroesb <email protected>(nl|com) + Just extended PHP with SNMPSET(). + **************************************************************************/ + + static int + ascii_to_binary(cp, bufp) + u_char *cp; + u_char *bufp; + { + int subidentifier; + u_char *bp = bufp; + + for(; *cp != '\0'; cp++){ + if (isspace(*cp)) + continue; + if (!isdigit(*cp)){ + php3_error(E_WARNING, "[snmp::ascii_to_binary] Input error\n"); + return -1; + } + subidentifier = atoi(cp); + if (subidentifier > 255){ + php3_error(E_WARNING, "[snmp::hex_to_binary] subidentifier %d is too large ( > 255)\n", + subidentifier); + return -1; + } + *bp++ = (u_char)subidentifier; + while(isdigit(*cp)) + cp++; + cp--; + } + return bp - bufp; + } + + static int + hex_to_binary(cp, bufp) + u_char *cp; + u_char *bufp; + { + int subidentifier; + u_char *bp = bufp; + + for(; *cp != '\0'; cp++){ + if (isspace(*cp)) + continue; + if (!isxdigit(*cp)){ + php3_error(E_WARNING, "[snmp::hex_to_binary] Input error\n"); + return -1; + } + sscanf((char *)cp, "%x", &subidentifier); + if (subidentifier > 255){ + php3_error(E_WARNING, "[snmp::hex_to_binary] subidentifier %d is too large ( > 255)\n", + subidentifier); + + return -1; + } + *bp++ = (u_char)subidentifier; + while(isxdigit(*cp)) + cp++; + cp--; + } + return bp - bufp; + } + + /* + * Add a variable with the requested name to the end of the list of + * variables for this pdu. + */ + int + snmp_add_var(pdu, name, name_length, type, value) + struct snmp_pdu *pdu; + oid *name; + int name_length; + char type, *value; + { + struct variable_list *vars; + char buf[2048]; + + if (pdu->variables == NULL){ + pdu->variables = vars = + (struct variable_list *)calloc(1, sizeof(struct variable_list)); + } else { + for(vars = pdu->variables; + vars->next_variable; + vars = vars->next_variable) + /*EXIT*/; + vars->next_variable = + (struct variable_list *)calloc(1, sizeof(struct variable_list)); + vars = vars->next_variable; + } + + vars->next_variable = NULL; + vars->name = (oid *)calloc(1, name_length * sizeof(oid)); + #ifdef SVR4 + memmove((char *)vars->name, (char *)name, name_length * sizeof(oid)); + #else + bcopy((char *)name, (char *)vars->name, name_length * sizeof(oid)); + #endif + vars->name_length = name_length; + + switch(type){ + case 'i': + vars->type = INTEGER; + vars->val.integer = (long *)calloc(1, sizeof(long)); + *(vars->val.integer) = atoi(value); + vars->val_len = sizeof(long); + break; + case 's': + case 'x': + case 'd': + vars->type = STRING; + if (type == 'd'){ + vars->val_len = ascii_to_binary((u_char *)value, buf); + } else if (type == 's'){ + strcpy(buf, value); + vars->val_len = strlen(buf); + } else if (type == 'x'){ + vars->val_len = hex_to_binary((u_char *)value, buf); + } + vars->val.string = (u_char *)calloc(1, vars->val_len); + #ifdef SVR4 + memmove((char *)vars->val.string, (char *)buf, vars->val_len); + #else + bcopy((char *)buf, (char *)vars->val.string, vars->val_len); + #endif + break; + case 'n': + vars->type = NULLOBJ; + vars->val_len = 0; + vars->val.string = NULL; + break; + case 'o': + vars->type = OBJID; + vars->val_len = MAX_NAME_LEN; + read_objid(value, (oid *)buf, &vars->val_len); + vars->val_len *= sizeof(oid); + vars->val.objid = (oid *)calloc(1, vars->val_len); + #ifdef SVR4 + memmove((char *)vars->val.objid, (char *)buf, vars->val_len); + #else + bcopy((char *)buf, (char *)vars->val.objid, vars->val_len); + #endif + break; + case 't': + vars->type = TIMETICKS; + vars->val.integer = (long *)calloc(1, sizeof(long)); + *(vars->val.integer) = atoi(value); + vars->val_len = sizeof(long); + break; + case 'a': + vars->type = IPADDRESS; + vars->val.integer = (long *)calloc(1, sizeof(long)); + *(vars->val.integer) = inet_addr(value); + vars->val_len = sizeof(long); + break; + default: + /* exit(-1); */ + return 0; + } + return 1; + } + + /* {{{ proto string snmpset(string host, string community, string object_id, string type, string value [, int timeout [, int retries]]) + Fetch an SNMP object */ + void php3_snmpset(INTERNAL_FUNCTION_PARAMETERS) + { + /* _php3_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,3); */ + + pval *a1, *a2, *a3, *a4, *a5, *a6, *a7; + struct snmp_session session, *ss; + struct snmp_pdu *pdu=NULL, *response; + struct variable_list *vars; + char *objid; + oid name[MAX_NAME_LEN]; + int name_length; + int status, count,rootlen=0,gotroot=0; + oid root[MAX_NAME_LEN]; + char buf[2048]; + int keepwalking=1; + long timeout=SNMP_DEFAULT_TIMEOUT; + long retries=SNMP_DEFAULT_RETRIES; + int myargc = ARG_COUNT(ht); + + int current_name = 0, current_type = 0, current_value = 0; + char *names[128], types[128], *values[128]; + int add_var_result; + + if (myargc<5 || myargc>7 || + getParameters(ht, myargc, &a1, &a2, &a3, &a4, &a5, &a6, &a7) == FAILURE) + { + WRONG_PARAM_COUNT; + } + convert_to_string(a1); + convert_to_string(a2); + convert_to_string(a3); + convert_to_string(a4); + types[current_type++] = *(a4->value.str.val); + convert_to_string(a5); + values[current_name++] = a5->value.str.val; + + if(myargc>5) + { + convert_to_long(a6); + timeout=a6->value.lval; + } + if(myargc>6) + { + convert_to_long(a7); + retries=a7->value.lval; + } + objid=a3->value.str.val; + memset(&session, 0, sizeof(struct snmp_session)); + session.peername = a1->value.str.val; + + session.version = SNMP_VERSION_1; + session.community = (u_char *)a2->value.str.val; + session.community_len = a2->value.str.len; + session.retries = retries; + session.timeout = timeout; + + session.authenticator = NULL; + snmp_synch_setup(&session); + ss = snmp_open(&session); + if (ss == NULL) + { + php3_error(E_WARNING,"Couldn't open snmp\n"); + RETURN_FALSE; + } + + pdu = snmp_pdu_create(SET_REQ_MSG); + name_length = MAX_NAME_LEN; + if (!read_objid(objid, name, &name_length)) { + php3_error(E_WARNING,"Invalid object identifier: %s\n", objid); + snmp_close(ss); + RETURN_FALSE; + } + + /* Just one TYPE, VALUE for now. That's why I indexes with"[0]" [Unk] */ + add_var_result = snmp_add_var(pdu, name, name_length, types[0], values[0]); + if (add_var_result <= 0) + { + php3_error(E_WARNING, "Internal error in type switching\n"); + snmp_close(ss); + RETURN_FALSE; + } + + retry: + status = snmp_synch_response(ss, pdu, &response); + if (status == STAT_SUCCESS) + { + if (response->errstat == SNMP_ERR_NOERROR) + { + if (response->command == REPORT_MSG) + { + for (vars = response->variables; vars; + vars = vars->next_variable) + sprint_value(buf, vars->name, vars->name_length, vars); + php3_error(E_WARNING, "This is an error report:%s\n", + snmp_errstring(response->errstat)); + /* snmp_close(ss); */ + RETURN_FALSE; + } + } else { + php3_error(E_WARNING, "Error in packet.\nReason: %s\n", + snmp_errstring(response->errstat)); + + if ((pdu = snmp_fix_pdu(response, SET_REQ_MSG)) != NULL) { + goto retry; + } + /* snmp_close(ss); */ + RETURN_FALSE; + } + + } else + if (status == STAT_TIMEOUT) + { + php3_error(E_WARNING, "No response from %s\n", a1->value.str.val); + /* snmp_close(ss); */ + RETURN_FALSE; + } else + { + php3_error(E_WARNING, "An error occurred, Quiting\n"); + /* snmp_close(ss); */ + RETURN_FALSE; + } + + if (response) snmp_free_pdu(response); + + snmp_close(ss); + RETURN_TRUE; + } + /* }}} */ + + #endif /* * Local variables: * tab-width: 4 * c-basic-offset: 4 + * End: */

[END diff]

-- PHP Development Mailing List http://www.php.net/ To unsubscribe send an empty message to php-dev-unsubscribe <email protected> For help: php-dev-help <email protected>