~ubuntu-branches/ubuntu/trusty/net-snmp/trusty

« back to all changes in this revision

Viewing changes to agent/agent_trap.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2007-12-08 14:59:50 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20071208145950-u1tykhpw56nyzqik
Tags: 5.4.1~dfsg-4ubuntu1
* Merge from debian unstable.
* Remaining Ubuntu changes:
  - Remove stop links from rc0 and rc6
  - Munge Maintainer field as per spec.
* Ubuntu changes dropped:
  - Symlink common files between the packages, CDBS ought to handle that
    for us automatically.
* The latest Debian changes has dropped history from the changelog. Slot in
  the Ubuntu changes as best I can. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
62
62
#include <net-snmp/agent/snmp_agent.h>
63
63
#include <net-snmp/agent/agent_callbacks.h>
64
64
 
 
65
#include <net-snmp/agent/agent_module_config.h>
65
66
#include <net-snmp/agent/mib_module_config.h>
66
67
 
67
68
#ifdef USING_AGENTX_PROTOCOL_MODULE
79
80
 
80
81
extern struct timeval starttime;
81
82
 
82
 
oid             objid_enterprisetrap[] = { NOTIFICATION_MIB };
83
 
oid             trap_version_id[] = { SYSTEM_MIB };
 
83
oid             objid_enterprisetrap[] = { NETSNMP_NOTIFICATION_MIB };
 
84
oid             trap_version_id[] = { NETSNMP_SYSTEM_MIB };
84
85
int             enterprisetrap_len;
85
86
int             trap_version_id_len;
86
87
 
107
108
size_t          agentaddr_oid_len;
108
109
oid             community_oid[] = { SNMPV2_COMM_OBJS_PREFIX, 4, 0 };
109
110
size_t          community_oid_len;
110
 
#if !defined(DISABLE_SNMPV1) || !defined(DISABLE_SNMPV2C)
 
111
#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
111
112
char           *snmp_trapcommunity = NULL;
112
113
#endif
113
114
 
224
225
    return 0;
225
226
}
226
227
 
227
 
#if !defined(DISABLE_SNMPV1) || !defined(DISABLE_SNMPV2C)
228
 
int
229
 
create_trap_session(char *sink, u_short sinkport,
230
 
                    char *com, int version, int pdutype)
 
228
#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
 
229
static int
 
230
create_trap_session2(const char *sink, const char* sinkport,
 
231
                     char *com, int version, int pdutype)
231
232
{
 
233
    netsnmp_transport *t;
232
234
    netsnmp_session session, *sesp;
233
 
    char           *peername = NULL;
234
 
    int             len;
235
 
 
236
 
    len = strlen(sink) + 4 + 32;
237
 
    if ((peername = malloc(len)) == NULL) {
238
 
        return 0;
239
 
    } else if (NULL != strchr(sink,':')) {
240
 
        snprintf(peername, len, "%s", sink);
241
 
    } else {
242
 
        snprintf(peername, len, "udp:%s:%hu", sink, sinkport);
243
 
    }
244
235
 
245
236
    memset(&session, 0, sizeof(netsnmp_session));
246
 
    session.peername = peername;
247
237
    session.version = version;
248
238
    if (com) {
249
239
        session.community = (u_char *) com;
265
255
                                       NETSNMP_DS_LIB_CLIENT_ADDR)) && 
266
256
        ((0 == strcmp("localhost",sink)) || (0 == strcmp("127.0.0.1",sink))))
267
257
        session.localname = "localhost";
268
 
    sesp = snmp_open(&session);
269
 
    free(peername);
270
 
 
271
 
    if (sesp) {
272
 
        return add_trap_session(sesp, pdutype,
273
 
                                (pdutype == SNMP_MSG_INFORM), version);
 
258
 
 
259
    t = netsnmp_tdomain_transport_full("snmptrap", sink, 0, NULL, sinkport);
 
260
    if (t != NULL) {
 
261
        sesp = snmp_add(&session, t, NULL, NULL);
 
262
 
 
263
        if (sesp) {
 
264
            return add_trap_session(sesp, pdutype,
 
265
                                    (pdutype == SNMP_MSG_INFORM), version);
 
266
        }
274
267
    }
275
 
 
276
268
    /*
277
269
     * diagnose snmp_open errors with the input netsnmp_session pointer 
278
270
     */
279
271
    snmp_sess_perror("snmpd: create_trap_session", &session);
280
272
    return 0;
281
273
}
 
274
 
 
275
int
 
276
create_trap_session(char *sink, u_short sinkport,
 
277
                    char *com, int version, int pdutype)
 
278
{
 
279
    char buf[sizeof(sinkport) * 3 + 2];
 
280
    if (sinkport != 0) {
 
281
        sprintf(buf, ":%hu", sinkport);
 
282
        snmp_log(LOG_NOTICE,
 
283
                 "Using a separate port number is deprecated, please correct "
 
284
                 "the sink specification instead");
 
285
    }
 
286
    return create_trap_session2(sink, sinkport ? buf : NULL, com, version,
 
287
                                pdutype);
 
288
}
 
289
 
282
290
#endif /* support for community based SNMP */
283
291
 
284
 
#ifndef DISABLE_SNMPV1
 
292
#ifndef NETSNMP_DISABLE_SNMPV1
285
293
static int
286
 
create_v1_trap_session(char *sink, u_short sinkport, char *com)
 
294
create_v1_trap_session(char *sink, const char *sinkport, char *com)
287
295
{
288
 
    return create_trap_session(sink, sinkport, com,
289
 
                               SNMP_VERSION_1, SNMP_MSG_TRAP);
 
296
    return create_trap_session2(sink, sinkport, com,
 
297
                                SNMP_VERSION_1, SNMP_MSG_TRAP);
290
298
}
291
299
#endif
292
300
 
293
 
#ifndef DISABLE_SNMPV2C
 
301
#ifndef NETSNMP_DISABLE_SNMPV2C
294
302
static int
295
 
create_v2_trap_session(char *sink, u_short sinkport, char *com)
 
303
create_v2_trap_session(const char *sink, const char *sinkport, char *com)
296
304
{
297
 
    return create_trap_session(sink, sinkport, com,
298
 
                               SNMP_VERSION_2c, SNMP_MSG_TRAP2);
 
305
    return create_trap_session2(sink, sinkport, com,
 
306
                                SNMP_VERSION_2c, SNMP_MSG_TRAP2);
299
307
}
300
308
 
301
309
static int
302
 
create_v2_inform_session(char *sink, u_short sinkport, char *com)
 
310
create_v2_inform_session(const char *sink, const char *sinkport, char *com)
303
311
{
304
 
    return create_trap_session(sink, sinkport, com,
305
 
                               SNMP_VERSION_2c, SNMP_MSG_INFORM);
 
312
    return create_trap_session2(sink, sinkport, com,
 
313
                                SNMP_VERSION_2c, SNMP_MSG_INFORM);
306
314
}
307
315
#endif
308
316
 
374
382
    }
375
383
 
376
384
    /*
 
385
     * Check the v2 varbind list for any varbinds
 
386
     *  that are not valid in an SNMPv1 trap.
 
387
     *  This basically means Counter64 values.
 
388
     *
 
389
     * RFC 2089 said to omit such varbinds from the list.
 
390
     * RFC 2576/3584 say to drop the trap completely.
 
391
     */
 
392
    for (var = vblist->next_variable; var; var = var->next_variable) {
 
393
        if ( var->type == ASN_COUNTER64 ) {
 
394
            snmp_log(LOG_WARNING,
 
395
                     "send_trap: v1 traps can't carry Counter64 varbinds\n");
 
396
            snmp_free_pdu(template_v1pdu);
 
397
            return NULL;
 
398
        }
 
399
    }
 
400
 
 
401
    /*
377
402
     * Set the generic & specific trap types,
378
403
     *    and the enterprise field from the v2 varbind list.
379
404
     * If there's an agentIPAddress varbind, set the agent_addr too
406
431
         *   into enterprise and specific trap
407
432
         */
408
433
        len = vblist->val_len / sizeof(oid);
 
434
        if ( len <= 2 ) {
 
435
            snmp_log(LOG_WARNING,
 
436
                     "send_trap: v2 trapOID too short (%d)\n", len);
 
437
            snmp_free_pdu(template_v1pdu);
 
438
            return NULL;
 
439
        }
409
440
        template_v1pdu->trap_type     = SNMP_TRAP_ENTERPRISESPECIFIC;
410
441
        template_v1pdu->specific_type = vblist->val.objid[len - 1];
411
442
        len--;
539
570
    var = find_varbind_in_list( template_v2pdu->variables,
540
571
                                snmptrapenterprise_oid,
541
572
                                snmptrapenterprise_oid_len);
542
 
    if (!var && 
543
 
        template_v1pdu->trap_type != SNMP_TRAP_ENTERPRISESPECIFIC) {
 
573
    if (!var) {
544
574
        if (!snmp_varlist_add_variable( &(template_v2pdu->variables),
545
575
                 snmptrapenterprise_oid, snmptrapenterprise_oid_len,
546
576
                 ASN_OBJECT_ID,
706
736
        if (!template_v1pdu) {
707
737
            snmp_log(LOG_WARNING,
708
738
                     "send_trap: failed to convert v2->v1 template PDU\n");
709
 
            snmp_free_pdu(template_v2pdu);
710
 
            return -1;
711
739
        }
712
740
 
713
741
    } else {
746
774
        if (!template_v2pdu) {
747
775
            snmp_log(LOG_WARNING,
748
776
                     "send_trap: failed to convert v1->v2 template PDU\n");
749
 
            snmp_free_pdu(template_v1pdu);
750
 
            return -1;
751
777
        }
752
778
    }
753
779
 
754
780
    /*
755
781
     * Check whether we're ignoring authFail traps
756
782
     */
757
 
    if (template_v1pdu->trap_type == SNMP_TRAP_AUTHFAIL &&
 
783
    if (template_v1pdu) {
 
784
      if (template_v1pdu->trap_type == SNMP_TRAP_AUTHFAIL &&
758
785
        snmp_enableauthentraps == SNMP_AUTHENTICATED_TRAPS_DISABLED) {
759
786
        snmp_free_pdu(template_v1pdu);
760
787
        snmp_free_pdu(template_v2pdu);
761
788
        return 0;
762
 
    }
 
789
      }
763
790
 
764
791
    /*
765
792
     * Ensure that the v1 trap PDU includes the local IP address
766
793
     */
767
 
     pdu_in_addr_t = (in_addr_t *) template_v1pdu->agent_addr;
768
 
    *pdu_in_addr_t = get_myaddr();
 
794
       pdu_in_addr_t = (in_addr_t *) template_v1pdu->agent_addr;
 
795
      *pdu_in_addr_t = get_myaddr();
 
796
    }
769
797
 
770
798
 
771
799
    /*
774
802
     *   providing an appropriately formatted PDU in each case
775
803
     */
776
804
    for (sink = sinks; sink; sink = sink->next) {
777
 
#ifndef DISABLE_SNMPV1
 
805
#ifndef NETSNMP_DISABLE_SNMPV1
778
806
        if (sink->version == SNMP_VERSION_1) {
 
807
          if (template_v1pdu) {
779
808
            send_trap_to_sess(sink->sesp, template_v1pdu);
 
809
          }
780
810
        } else {
781
811
#endif
 
812
          if (template_v2pdu) {
782
813
            template_v2pdu->command = sink->pdutype;
783
814
            send_trap_to_sess(sink->sesp, template_v2pdu);
784
 
#ifndef DISABLE_SNMPV1
 
815
          }
 
816
#ifndef NETSNMP_DISABLE_SNMPV1
785
817
        }
786
818
#endif
787
819
    }
788
 
    snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
 
820
    if (template_v1pdu)
 
821
        snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
789
822
                        SNMPD_CALLBACK_SEND_TRAP1, template_v1pdu);
790
 
    snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
 
823
    if (template_v2pdu)
 
824
        snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
791
825
                        SNMPD_CALLBACK_SEND_TRAP2, template_v2pdu);
792
826
    snmp_free_pdu(template_v1pdu);
793
827
    snmp_free_pdu(template_v2pdu);
855
889
{
856
890
    netsnmp_pdu    *pdu;
857
891
    int            result;
 
892
    char           tmp[SPRINT_MAX_LEN];
 
893
    int            len;
 
894
 
858
895
 
859
896
    if (!sess || !template_pdu)
860
897
        return;
862
899
    DEBUGMSGTL(("trap", "sending trap type=%d, version=%d\n",
863
900
                template_pdu->command, sess->version));
864
901
 
865
 
#ifndef DISABLE_SNMPV1
 
902
#ifndef NETSNMP_DISABLE_SNMPV1
866
903
    if (sess->version == SNMP_VERSION_1 &&
867
904
        (template_pdu->command != SNMP_MSG_TRAP))
868
905
        return;                 /* Skip v1 sinks for v2 only traps */
 
906
    if (sess->version != SNMP_VERSION_1 &&
 
907
        (template_pdu->command == SNMP_MSG_TRAP))
 
908
        return;                 /* Skip v2+ sinks for v1 only traps */
869
909
#endif
870
910
    template_pdu->version = sess->version;
871
911
    pdu = snmp_clone_pdu(template_pdu);
880
920
            snmp_async_send(sess, pdu, &handle_inform_response, NULL);
881
921
        
882
922
    } else {
 
923
        if ((sess->version == SNMP_VERSION_3) &&
 
924
                (pdu->command == SNMP_MSG_TRAP2) &&
 
925
                (pdu->securityEngineIDLen == 0)) {
 
926
            len = snmpv3_get_engineID(tmp, sizeof(tmp));
 
927
            memdup(&pdu->securityEngineID, tmp, len);
 
928
            pdu->securityEngineIDLen = len;
 
929
        }
 
930
 
883
931
        result = snmp_send(sess, pdu);
884
932
    }
885
933
 
910
958
 *
911
959
 * This function eventually calls send_enterprise_trap_vars.  If the
912
960
 * trap type is not set to SNMP_TRAP_ENTERPRISESPECIFIC the enterprise 
913
 
 * and enterprise_length paramater is set to the pre defined SYSTEM_MIB 
 
961
 * and enterprise_length paramater is set to the pre defined NETSNMP_SYSTEM_MIB 
914
962
 * oid and length respectively.  If the trap type is set to 
915
963
 * SNMP_TRAP_ENTERPRISESPECIFIC the enterprise and enterprise_length 
916
 
 * parameters are set to the pre-defined NOTIFICATION_MIB oid and length 
 
964
 * parameters are set to the pre-defined NETSNMP_NOTIFICATION_MIB oid and length 
917
965
 * respectively.
918
966
 *
919
967
 * @param trap is the generic trap type.
940
988
 *
941
989
 * This function eventually calls send_enterprise_trap_vars.  If the
942
990
 * trap type is not set to SNMP_TRAP_ENTERPRISESPECIFIC the enterprise 
943
 
 * and enterprise_length paramater is set to the pre defined SYSTEM_MIB 
 
991
 * and enterprise_length paramater is set to the pre defined NETSNMP_SYSTEM_MIB 
944
992
 * oid and length respectively.  If the trap type is set to 
945
993
 * SNMP_TRAP_ENTERPRISESPECIFIC the enterprise and enterprise_length 
946
 
 * parameters are set to the pre-defined NOTIFICATION_MIB oid and length 
 
994
 * parameters are set to the pre-defined NETSNMP_NOTIFICATION_MIB oid and length 
947
995
 * respectively.
948
996
 *
949
997
 * @param vars is used to supply list of variable bindings to form an SNMPv2 
1023
1071
    }
1024
1072
}
1025
1073
 
1026
 
#ifndef DISABLE_SNMPV1
 
1074
#ifndef NETSNMP_DISABLE_SNMPV1
1027
1075
void
1028
1076
snmpd_parse_config_trapsink(const char *token, char *cptr)
1029
1077
{
1030
1078
    char            tmpbuf[1024];
1031
1079
    char           *sp, *cp, *pp = NULL;
1032
 
    int             sinkport;
1033
1080
    char            *st;
1034
1081
 
1035
1082
    if (!snmp_trapcommunity)
1038
1085
    cp = strtok_r(NULL, " \t\n", &st);
1039
1086
    if (cp)
1040
1087
        pp = strtok_r(NULL, " \t\n", &st);
1041
 
    if (cp && pp) {
1042
 
        sinkport = atoi(pp);
1043
 
        if ((sinkport < 1) || (sinkport > 0xffff)) {
1044
 
            config_perror("trapsink port out of range");
1045
 
            sinkport = SNMP_TRAP_PORT;
1046
 
        }
1047
 
    } else {
1048
 
        sinkport = SNMP_TRAP_PORT;
1049
 
    }
1050
 
    if (create_v1_trap_session(sp, (u_short)sinkport,
1051
 
                               cp ? cp : snmp_trapcommunity) == 0) {
 
1088
    if (pp)
 
1089
        config_pwarn("The separate port argument to trapsink is deprecated");
 
1090
    if (create_v1_trap_session(sp, pp, cp ? cp : snmp_trapcommunity) == 0) {
1052
1091
        snprintf(tmpbuf, sizeof(tmpbuf), "cannot create trapsink: %s", cptr);
1053
1092
        tmpbuf[sizeof(tmpbuf)-1] = '\0';
1054
1093
        config_perror(tmpbuf);
1056
1095
}
1057
1096
#endif
1058
1097
 
1059
 
#ifndef DISABLE_SNMPV2C
 
1098
#ifndef NETSNMP_DISABLE_SNMPV2C
1060
1099
void
1061
1100
snmpd_parse_config_trap2sink(const char *word, char *cptr)
1062
1101
{
1071
1110
    cp = strtok_r(NULL, " \t\n", &st);
1072
1111
    if (cp)
1073
1112
        pp = strtok_r(NULL, " \t\n", &st);
1074
 
    if (cp && pp) {
1075
 
        sinkport = atoi(pp);
1076
 
        if ((sinkport < 1) || (sinkport > 0xffff)) {
1077
 
            config_perror("trapsink port out of range");
1078
 
            sinkport = SNMP_TRAP_PORT;
1079
 
        }
1080
 
    } else {
1081
 
        sinkport = SNMP_TRAP_PORT;
1082
 
    }
1083
 
    if (create_v2_trap_session(sp, (u_short)sinkport,
1084
 
                               cp ? cp : snmp_trapcommunity) == 0) {
 
1113
    if (pp)
 
1114
        config_pwarn("The separate port argument to trapsink2 is deprecated");
 
1115
    if (create_v2_trap_session(sp, pp, cp ? cp : snmp_trapcommunity) == 0) {
1085
1116
        snprintf(tmpbuf, sizeof(tmpbuf), "cannot create trap2sink: %s", cptr);
1086
1117
        tmpbuf[sizeof(tmpbuf)-1] = '\0';
1087
1118
        config_perror(tmpbuf);
1102
1133
    cp = strtok_r(NULL, " \t\n", &st);
1103
1134
    if (cp)
1104
1135
        pp = strtok_r(NULL, " \t\n", &st);
1105
 
    if (cp && pp) {
1106
 
        sinkport = atoi(pp);
1107
 
        if ((sinkport < 1) || (sinkport > 0xffff)) {
1108
 
            config_perror("trapsink port out of range");
1109
 
            sinkport = SNMP_TRAP_PORT;
1110
 
        }
1111
 
    } else {
1112
 
        sinkport = SNMP_TRAP_PORT;
1113
 
    }
1114
 
    if (create_v2_inform_session(sp, (u_short)sinkport,
1115
 
                                 cp ? cp : snmp_trapcommunity) == 0) {
 
1136
    if (pp)
 
1137
        config_pwarn("The separate port argument to informsink is deprecated");
 
1138
    if (create_v2_inform_session(sp, pp, cp ? cp : snmp_trapcommunity) == 0) {
1116
1139
        snprintf(tmpbuf, sizeof(tmpbuf), "cannot create informsink: %s", cptr);
1117
1140
        tmpbuf[sizeof(tmpbuf)-1] = '\0';
1118
1141
        config_perror(tmpbuf);
1153
1176
    char           *argv[MAX_ARGS], *cp = cptr, tmp[SPRINT_MAX_LEN];
1154
1177
    int             argn, arg;
1155
1178
    netsnmp_session session, *ss;
 
1179
    size_t          len;
1156
1180
 
1157
1181
    /*
1158
1182
     * inform or trap?  default to trap 
1169
1193
    }
1170
1194
 
1171
1195
    arg = snmp_parse_args(argn, argv, &session, "C:", trapOptProc);
1172
 
    ss = snmp_open(&session);
1173
1196
 
 
1197
    ss = snmp_add(&session,
 
1198
                  netsnmp_transport_open_client("snmptrap", session.peername),
 
1199
                  NULL, NULL);
1174
1200
    for (; argn > 0; argn--) {
1175
1201
        free(argv[argn - 1]);
1176
1202
    }
1182
1208
        return;
1183
1209
    }
1184
1210
 
1185
 
#ifndef DISABLE_SNMPV1
 
1211
    /*
 
1212
     * If this is an SNMPv3 TRAP session, then the agent is
 
1213
     *   the authoritative engine, so set the engineID accordingly
 
1214
     */
 
1215
    if (ss->version == SNMP_VERSION_3 &&
 
1216
        traptype != SNMP_MSG_INFORM   &&
 
1217
        ss->securityEngineIDLen == 0) {
 
1218
            len = snmpv3_get_engineID( tmp, sizeof(tmp));
 
1219
            memdup(&ss->securityEngineID, tmp, len);
 
1220
            ss->securityEngineIDLen = len;
 
1221
    }
 
1222
 
 
1223
#ifndef NETSNMP_DISABLE_SNMPV1
1186
1224
    if (ss->version == SNMP_VERSION_1) {
1187
1225
        add_trap_session(ss, SNMP_MSG_TRAP, 0, SNMP_VERSION_1);
1188
1226
    } else {
1189
1227
#endif
1190
1228
        add_trap_session(ss, traptype, (traptype == SNMP_MSG_INFORM),
1191
1229
                         ss->version);
1192
 
#ifndef DISABLE_SNMPV1
 
1230
#ifndef NETSNMP_DISABLE_SNMPV1
1193
1231
    }
1194
1232
#endif
1195
1233
}
1196
1234
 
1197
 
#if !defined(DISABLE_SNMPV1) || !defined(DISABLE_SNMPV2C)
 
1235
#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
1198
1236
void
1199
1237
snmpd_parse_config_trapcommunity(const char *word, char *cptr)
1200
1238
{