EN JA
SNMPMOD(3)
SNMPMOD(3) FreeBSD Library Functions Manual SNMPMOD(3)

名称

INSERT_OBJECT_OID_LINK_INDEX, INSERT_OBJECT_INT_LINK_INDEX, FIND_OBJECT_OID_LINK_INDEX, NEXT_OBJECT_OID_LINK_INDEX, FIND_OBJECT_INT_LINK_INDEX, NEXT_OBJECT_INT_LINK_INDEX, INSERT_OBJECT_OID_LINK, INSERT_OBJECT_INT_LINK, FIND_OBJECT_OID_LINK, NEXT_OBJECT_OID_LINK, FIND_OBJECT_INT_LINK, NEXT_OBJECT_INT_LINK, INSERT_OBJECT_OID, INSERT_OBJECT_INT, FIND_OBJECT_OID, FIND_OBJECT_INT, NEXT_OBJECT_OID, NEXT_OBJECT_INT, this_tick, start_tick, get_ticks, systemg, comm_define, community, oid_zeroDotZero, oid_usmUnknownEngineIDs, oid_usmNotInTimeWindows, reqid_allocate, reqid_next, reqid_base, reqid_istype, reqid_type, timer_start, timer_start_repeat, timer_stop, fd_select, fd_deselect, fd_suspend, fd_resume, or_register, or_unregister, buf_alloc, buf_size, snmp_input_start, snmp_input_finish, snmp_output, snmp_send_port, snmp_send_trap, snmp_pdu_auth_access string_save, string_commit, string_rollback, string_get, string_get_max, string_free, ip_save, ip_rollback, ip_commit, ip_get, oid_save, oid_rollback, oid_commit, oid_get, index_decode, index_compare, index_compare_off, index_append, index_append_off, snmpd_usmstats, bsnmpd_get_usm_stats, bsnmpd_reset_usm_stats, usm_first_user, usm_next_user, usm_find_user, usm_new_user, usm_delete_user, usm_flush_users, usm_user snmpd_target_stat bsnmpd_get_target_stats target_first_address target_next_address target_new_address target_activate_address target_delete_address target_first_param target_next_param target_new_param target_delete_param target_first_notify target_next_notify target_new_notify target_delete_notify target_flush_all target_address target_param target_notifySNMP デーモンローダブルモジュールインタフェース

ライブラリ

Begemot SNMP ライブラリ (libbsnmp, -lbsnmp)

書式

#include < bsnmp/snmpmod.h>

INSERT_OBJECT_OID_LINK_INDEX( PTR, LIST, LINK, INDEX);

INSERT_OBJECT_INT_LINK_INDEX( PTR, LIST, LINK, INDEX);

FIND_OBJECT_OID_LINK_INDEX( LIST, OID, SUB, LINK, INDEX);

FIND_OBJECT_INT_LINK_INDEX( LIST, OID, SUB, LINK, INDEX);

NEXT_OBJECT_OID_LINK_INDEX( LIST, OID, SUB, LINK, INDEX);

NEXT_OBJECT_INT_LINK_INDEX( LIST, OID, SUB, LINK, INDEX);

INSERT_OBJECT_OID_LINK( PTR, LIST, LINK);

INSERT_OBJECT_INT_LINK( PTR, LIST, LINK);

FIND_OBJECT_OID_LINK( LIST, OID, SUB, LINK);

FIND_OBJECT_INT_LINK( LIST, OID, SUB, LINK);

NEXT_OBJECT_OID_LINK( LIST, OID, SUB, LINK);

NEXT_OBJECT_INT_LINK( LIST, OID, SUB, LINK);

INSERT_OBJECT_OID( PTR, LIST);

INSERT_OBJECT_INT( PTR, LIST);

FIND_OBJECT_OID( LIST, OID, SUB);

FIND_OBJECT_INT( LIST, OID, SUB);

NEXT_OBJECT_OID( LIST, OID, SUB);

NEXT_OBJECT_INT( LIST, OID, SUB);

extern uint64_t this_tick;
extern uint64_t start_tick;

uint64_t
get_ticks( void);

extern struct systemg systemg;

u_int
comm_define( u_int priv, const char *descr, struct lmodule *mod, const char *str);

const char *
comm_string( u_int comm);

extern u_int community;
extern const struct asn_oid oid_zeroDotZero;

u_int
reqid_allocate( int size, struct lmodule *mod);

int32_t
reqid_next( u_int type);

int32_t
reqid_base( u_int type);

int
reqid_istype( int32_t reqid, u_int type);

u_int
reqid_type( int32_t reqid);

void *
timer_start( u_int ticks, void (*func)(void *), void *uarg, struct lmodule *mod);

void *
timer_start_repeat( u_int ticks, u_int repeat_ticks, void (*func)(void *), void *uarg, struct lmodule *mod);

void
timer_stop( void *timer_id);

void *
fd_select( int fd, void (*func)(int, void *), void *uarg, struct lmodule *mod);

void
fd_deselect( void *fd_id);

void
fd_suspend( void *fd_id);

int
fd_resume( void *fd_id);

u_int
or_register( const struct asn_oid *oid, const char *descr, struct lmodule *mod);

void
or_unregister( u_int or_id);

void *
buf_alloc( int tx);

size_t
buf_size( int tx);

enum snmpd_input_err
snmp_input_start( const u_char *buf, size_t len, const char *source, struct snmp_pdu *pdu, int32_t *ip, size_t *pdulen);

enum snmpd_input_err
snmp_input_finish( struct snmp_pdu *pdu, const u_char *rcvbuf, size_t rcvlen, u_char *sndbuf, size_t *sndlen, const char *source, enum snmpd_input_err ierr, int32_t ip, void *data);

void
snmp_output( struct snmp_pdu *pdu, u_char *sndbuf, size_t *sndlen, const char *dest);

void
snmp_send_port( void *trans, const struct asn_oid *port, struct snmp_pdu *pdu, const struct sockaddr *addr, socklen_t addrlen);

void
snmp_send_trap( const struct asn_oid *oid, ...);

enum snmp_code
snmp_pdu_auth_access( struct snmp_pdu *pdu, int32_t *ip);

int
string_save( struct snmp_value *val, struct snmp_context *ctx, ssize_t req_size, u_char **strp);

void
string_commit( struct snmp_context *ctx);

void
string_rollback( struct snmp_context *ctx, u_char **strp);

int
string_get( struct snmp_value *val, const u_char *str, ssize_t len);

int
string_get_max( struct snmp_value *val, const u_char *str, ssize_t len, size_t maxlen);

void
string_free( struct snmp_context *ctx);

int
ip_save( struct snmp_value *val, struct snmp_context *ctx, u_char *ipa);

void
ip_rollback( struct snmp_context *ctx, u_char *ipa);

void
ip_commit( struct snmp_context *ctx);

int
ip_get( struct snmp_value *val, u_char *ipa);

int
oid_save( struct snmp_value *val, struct snmp_context *ctx, struct asn_oid *oid);

void
oid_rollback( struct snmp_context *ctx, struct asn_oid *oid);

void
oid_commit( struct snmp_context *ctx);

int
oid_get( struct snmp_value *val, const struct asn_oid *oid);

int
index_decode( const struct asn_oid *oid, u_int sub, u_int code, ...);

int
index_compare( const struct asn_oid *oid1, u_int sub, const struct asn_oid *oid2);

int
index_compare_off( const struct asn_oid *oid1, u_int sub, const struct asn_oid *oid2, u_int off);

void
index_append( struct asn_oid *dst, u_int sub, const struct asn_oid *src);

void
index_append_off( struct asn_oid *dst, u_int sub, const struct asn_oid *src, u_int off);

extern struct snmpd_usmstat snmpd_usmstats;

struct snmpd_usmstat *
bsnmpd_get_usm_stats( void);

void
bsnmpd_reset_usm_stats( void);

struct usm_user *
usm_first_user( void);

struct usm_user *
usm_next_user( struct usm_user *uuser);

struct usm_user *
usm_find_user( uint8_t *engine, uint32_t elen, char *uname);

struct usm_user *
usm_new_user( uint8_t *engine, uint32_t elen, char *uname);

void
usm_delete_user( struct usm_user *);

void
usm_flush_users( void);

extern struct usm_user *usm_user;

struct snmpd_target_stats *
bsnmpd_get_target_stats( void);

struct target_address *
target_first_address( void);

struct target_address *
target_next_address( struct target_address *);

struct target_address *
target_new_address( char *);

int
target_activate_address( struct target_address *);

int
target_delete_address( struct target_address *);

struct target_param *
target_first_param( void);

struct target_param *
target_next_param( struct target_param *);

struct target_param *
target_new_param( char *);

int
target_delete_param( struct target_param *);

struct target_notify *
target_first_notify( void);

struct target_notify *
target_next_notify( struct target_notify *);

struct target_notify *
target_new_notify( char *);

int
target_delete_notify( struct target_notify *);

void
target_flush_all( void);

extern const struct asn_oid oid_usmUnknownEngineIDs;
extern const struct asn_oid oid_usmNotInTimeWindows;

解説

bsnmpd(1) SNMP デーモンは、システムグループから成る最小の MIB、 SNMP MIB の一部、プライベート設定 MIB、トラップ宛先テーブル、 UDP ポートテーブル、コミュニティテーブル、モジュールテーブル、統計グループとデバッググループを実装します。他のすべての MIB は、ローダブルモジュールを通してサポートされます。古典的な SNMP タスクではない、タスクのために bsnmpd(1) 使用することができます。

モジュールのロードとアンロード

モジュールは、モジュールテーブルに書き込むことによってロードされます。このテーブルは、デーモンへのモジュールを識別する、文字列によってインデックス付けされます。この識別子は、設定ファイルから正しい設定セクションを選択して、このモジュールに割り付けられたリソースを識別するために使用されます。モジュールテーブルの行は、 begemotSnmpdModulePath カラムに 0 でない長さの文字列を書き込むよって作成されます。この文字列は、モジュールを含むファイルへの完全なパスでなければなりません。モジュールは、既存の行のパスカラムに 0 の長さの文字列を書き込むことによって、アンロードすることができます。

モジュールを互いに依存しているかもしれないので、正しい順序でロードしなければなりません。依存は、対応するマニュアルページにリストされています。

モジュールをロードするとき、SNMP デーモンは、グローバルシンボル config をエクスポートするモジュールファイルを期待します。このシンボルは、タイプ struct snmp_module の変数であるべきです:

typedef enum snmpd_proxy_err (*proxy_err_f)(struct snmp_pdu *, void *, 
    const struct asn_oid *, const struct sockaddr *, socklen_t, 
    enum snmpd_input_err, int32_t); 
 
 
struct snmp_module { 
 const char *comment; 
 int (*init)(struct lmodule *, int argc, char *argv[]); 
 int (*fini)(void); 
 void (*idle)(void); 
 void (*dump)(void); 
 void (*config)(void); 
 void (*start)(void); 
 proxy_err_f proxy; 
 const struct snmp_node *tree; 
 u_int tree_size; 
 void (*loading)(const struct lmodule *, int); 
};

この構造体は、静的に初期化しなければなりません、そして、フィールドには、次の関数があります:

comment
これは、モジュールテーブルで目に見える文字列です。それは、このモジュールの関数に関して何らかのヒントを与えるべきです。
init
この関数は、モジュールをロードするとき呼び出されます。モジュールポインタは、他の呼び出しで必要であるので、モジュールによって収納されるべきです、そして、引数ベクトルは、デーモンコマンド行からのこのモジュールへの引数を含みます。この関数は、すべてがうまくいくなら、0 を返すか、または UNIX エラーコード ( errno(3) を参照) を返すべきです。いったんモジュールが 0 を返すと、 fini 関数は、モジュールがアンロードされるとき、呼び出されます。
fini
モジュールは、アンロードされます。これは、自動的に解放されないリソースを解放する機会をモジュールに与えます。デーモンは、非常に長い間実行する傾向があるので、必ず、すべてのメモリを解放してください。この関数ポインタは、それは必要でないなら、 NULL であるかもしれません。
idle
この関数ポインタが NULL でないなら、それによって指された関数は、デーモンがイベントを待とうとしているときは、常に呼び出されます。この機能を使用することは避けるようにしてください。
dump
デーモンが SIGUSR1 を受け取るときはいつも、それは、 syslog(3) を通して内部状態をダンプします。 dump フィールドが NULL でないなら、モジュールの状態をダンプするためにデーモンによって呼び出されます。
config
デーモンが SIGHUP シグナルを受け取るときはいつも、設定ファイルを再び読み込みます。 config フィールドが NULL でないなら、新しい設定に適応する機会をモジュールに与えるために設定ファイルを読み込んだ後で呼び出されます。
start
NULL でないなら、この関数は、ローディングが成功した後に呼び出され、実際の操作を開始するためにモジュールを初期化しています。
proxy
デーモンが PDU を受け取り、その PDU がコミュニティ文字列を持っているなら、だれのコミュニティであるかは、このモジュールによって登録されて、 proxy は、この関数が PDU を取り扱うために呼び出される NULL ではありません。
tree
これは、このモジュールによって実装された MIB ツリーのためのノード配列へのポインタです。
tree_size
これは、 tree のノードの数です。
loading
このポインタが NULL でないなら、別のモジュールがロードされるか、またはアンロードされるときは常に呼び出されます。それは、そのモジュールとフラグへのポインタを取得します。フラグは、アンロードのためには、0、ロードのためには、1 です。

すべてがうまくいくときに、デーモンは、モジュールの MIB ツリーを現在のグローバルツリーにマージし、モジュール init() 関数を呼び出します。この関数がエラーを返すなら、モジュール MIB ツリーは、グローバルなものから取り除かれ、モジュールをアンロードします。初期化が成功するなら、モジュール start() 関数が呼び出されます。返った後に、(ロードされたものを含んで) すべてのモジュールの loaded() (ロードされた) 関数は、呼び出されます。

モジュールがアンロードされるとき、その MIB ツリーは、グローバルなものから取り除かれ、コミュニティ、要求 ID 範囲、実行タイマと選択されたファイル記述子は、解放され、 fini() 関数は、呼び出され、モジュールファイルは、アンロードされ、そして、他のすべてのモジュールの loaded() (ロードされた) 関数は、呼び出されます。

実装テーブル

実装された SNMP テーブルを助けになるように設計された多くのマクロがあります。テーブルの実装の間の問題は、GETNEXT 操作のサポートです。 GETNEXT 操作は、与えられた任意の OID、最も少ないテーブル列、与えられた OID より高い OID があるかどうか見つけなければなりません。これを行う最も簡単な方法は、テーブル列のインデックスがある OID を含むそれぞれの構造体の順序付けられたリストとしてテーブルを保持することです。これは、簡単な取り外し、挿入、および検索を可能にします。

手助けマクロは、テーブルが TAILQ queue(3) 参照) として組織化され、各構造体がインデックスとして使用される struct asn_oid を含むことを仮定します。整数か符号なしインデックスだけの単純なテーブルのために、インデックスフィールドとして整数か符号なしフィールドの存在を仮定する、マクロの代わりの形式が利用可能です。

マクロには、次の形式の名前があります。

{INSERT,FIND,NEXT}_OBJECT_{OID,INT}[_LINK[_INDEX]]

INSERT_*() マクロは、新しいテーブル列をテーブルに挿入するための SET 操作で使用されます。 FIND_*() マクロは、テーブルで特定の列を見つけるための GET 操作で使用されます。 NEXT_*() マクロは、テーブルで次の列を見つけるための GETNEXT 操作で使用されます。最後の 2 つのマクロは、列が見つけられるなら、列の構造体へのポインタを返し、そうでなければ、 NULL を返します。マクロ *_OBJECT_OID_*() は、インデックスとして使用される struct asn_oid が存在していると仮定し、マクロ *_OBJECT_INT_*() は、インデックスとして使用される符号なし整数フィールドが存在していると仮定します。

マクロ *_INDEX() は、パラメータ INDEX のインデックスフィールドの明白な名前付けを可能としますが、他のマクロは、このフィールドが index と名前が付けられていると仮定します。マクロ *_LINK_*() は、テールキューのリンクフィールドの明白な名前付けを可能とし、他のマクロは、リンクフィールドが link と名前が付けられていると仮定します。同じ構造が 2 つ以上の異なったテーブルに保持されるなら、明らかに名前が付けられたリンクフィールドが必要であるかもしれません。

マクロへの引数は、次の通りです:

PTR
テーブルに挿入される新しい構造体へのポインタ。
LIST
テールキューヘッドへのポインタ。
LINK
列の構造体のリンクフィールドの名前。
INDEX
列の構造体のインデックスフィールドの名前。
OID
ノード操作コールバックへの value 引数の var フィールドへのポインタでなければなりません。これは、検索するための OID です。
SUB
これは、 OID によって指された OID のテーブルインデックスの始まりのインデックスです。通常、これは、ノード操作コールバックへの sub 引数と同じです。

デーモンタイムスタンプ

変数 this_tick は、現在の PDU 処理が始められたとき、(1 秒間に 100 SNMP チック (tick) がある) 時間のチック (tick) を含んでいます。変数 start_tick は、デーモンが始められたとき、時間のチックを含んでいます。関数 get_ticks() は、現在のチックを返します。デーモンが始められて以来のチックの数は、次の通りです。

get_ticks() - start_tick

システムグループ

システムグループのスカラフールドは、グローバル変数 systemg に保持されます:

struct systemg { 
 u_char  *descr; 
 struct asn_oid object_id; 
 u_char  *contact; 
 u_char  *name; 
 u_char  *location; 
 uint32_t services; 
 uint32_t or_last_change; 
};

コミュニティ

SNMP デーモンは、コミュニティテーブルを実装します。要求メッセージを受け取り次第、そのメッセージのコミュニティ文字列は、そのテーブルのそれぞれのコミュニティ文字列と比較され、一致が見つけられるなら、グローバル変数 community は、そのコミュニティのためのコミュニティ識別子に設定されます。コミュニティ識別子は、符号なし整数です。 3 つの標準のコミュニティには、次のように定義された 3 つの定数があります:

#define COMM_INITIALIZE 0 
#define COMM_READ 1 
#define COMM_WRITE 2

community は、設定ファイルの代入が処理されている間、 COMM_INITIALIZE に設定されます。読み込み書き込み、または読み込み専用コミュニティのためのコミュニティ文字列が着信 PDU で見つけられたとき、 COMM_READ または COMM_WRITE に設定されます。

モジュールは、追加コミュニティを定義することができます。これは、転送プロキシ (1 つの通信リンクで受信された PDU が別のリンクにプロキシされる) を提供するか、または SNMP への非 UDP アクセスポイントを実装する必要があるかもしれません。新しいコミュニティは、関数 comm_define() で定義されます。それは、次のパラメータを取ります:

priv
これは、モジュールにコミュニティを識別する整数です。各モジュールには、このパラメータに関してそれ自体の名前空間があります。コミュニティテーブルは、モジュール名とこの識別子でインデックス付けされます。
descr
これは、コミュニティの人間に解読可能な説明を提供する文字列です。それは、コミュニティテーブルで目に見えます。
mod
これは、コミュニティを定義するモジュールです。
str
これは、初期のコミュニティ文字列です。

関数は、グローバルでユニークなコミュニティ識別子を返します。 SNMPv1 または SNMPv2 PDU が一致するコミュニティ文字列を受信するなら、この識別子は、グローバルな community に設定されます。

関数 comm_string() は、与えられたコミュニティのための現在のコミュニティ文字列を返します。

モジュールによって定義されたすべてのコミュニティは、モジュールがアンロードされるとき、自動的に解放されます。

ユーザベースのセキュリティグループ

USM グループのスカラの統計値は、グローバル変数 snmpd_usmstats に保持されます:

struct snmpd_usmstat { 
 uint32_t unsupported_seclevels; 
 uint32_t not_in_time_windows; 
 uint32_t unknown_users; 
 uint32_t unknown_engine_ids; 
 uint32_t wrong_digests; 
 uint32_t decrypt_errors; 
};

bsnmpd_get_usm_stats() は、統計を含むグローバルな構造体へのポインタを返します。 bsnmpd_reset_usm_stats() は、USM グループの統計値をクリアします。

設定された USM ユーザのグローバルなリストは、デーモンによって保守されています。

struct usm_user { 
 struct snmp_user  suser; 
 uint8_t    user_engine_id[SNMP_ENGINE_ID_SIZ]; 
 uint32_t   user_engine_len; 
 char    user_public[SNMP_ADM_STR32_SIZ]; 
 uint32_t   user_public_len; 
 int32_t    status; 
 int32_t    type; 
 SLIST_ENTRY(usm_user)  up; 
};

この構造体は、USM ユーザを表します。デーモンは、グローバルなリストの USM ユーザエントリにマッチするユーザ資格証明でのみ SNMPv3 PDU に応答します。セキュリティモデルが USM で、SNMPv3 PDU が受信されるなら、グローバルな usm_user は、PDU に含まれた資格証明にマッチするユーザエントリを指すように設定されます。しかしながら、デーモンは、USM ユーザを作成も削除もしないで、リストを管理するために外部のロード可能な (複数の) モジュールへのインタフェースを与えます。 usm_new_user() は、リストにユーザエントリを追加し、 usm_delete_user() は、リストから既存のエントリを削除します。 usm_flush_users() は、すべての設定された USM ユーザを削除するために使用されます。 usm_first_user() は、リストの最初のユーザを返し、リストが空であるなら、 NULL を返します。 usm_next_user() は、存在するなら、与えられたエントリの次のユーザを返し、そうでなければ NULL を返します。りすとは、USM ユーザ名と Engine ID に従ってソートされます。 usm_find_user() は、与えられた engineuname にマッチする USM ユーザエントリを返し、指定された名前とエンジン ID があるユーザがリスト中に存在していないなら、 NULL を返します。

管理ターゲットグループ

Management Target グループは、SNMPv3 通知を SNMPv3 を送信するとき、使用されるターゲットアドレス情報を保持しています。

Management Target グループのスカラの統計は、グローバル変数 snmpd_target_stats に保持されています:

struct snmpd_target_stats { 
 uint32_t   unavail_contexts; 
 uint32_t   unknown_contexts; 
};

bsnmpd_get_target_stats() は、統計を含むグローバル構造体へのポインタを返します。

設定された管理ターゲットアドレス、パラメータと通知の 3 つのグローバルなリストは、それぞれ、デーモンによって維持されます。

struct target_address { 
 char    name[SNMP_ADM_STR32_SIZ]; 
 uint8_t    address[SNMP_UDP_ADDR_SIZ]; 
 int32_t    timeout; 
 int32_t    retry; 
 char    taglist[SNMP_TAG_SIZ]; 
 char    paramname[SNMP_ADM_STR32_SIZ]; 
 int32_t    type; 
 int32_t    socket; 
 int32_t    status; 
 SLIST_ENTRY(target_address) ta; 
};

この構造体は、SNMPv3 Management Target アドレスを表します。 SNMP TRAP が送信されるたびに、デーモンは、グローバルなリストのすべてのアクティブな Management Target アドレスに Trap を送信します。

struct target_param { 
 char    name[SNMP_ADM_STR32_SIZ]; 
 int32_t    mpmodel; 
 int32_t    sec_model; 
 char    secname[SNMP_ADM_STR32_SIZ]; 
 enum snmp_usm_level  sec_level; 
 int32_t    type; 
 int32_t    status; 
 SLIST_ENTRY(target_param) tp; 
};

この構造体は、関連する SNMPv3 Management Target アドレスへの SNMP メッセージを生成するのに使用される情報を表します。

struct target_notify { 
 char    name[SNMP_ADM_STR32_SIZ]; 
 char    taglist[SNMP_TAG_SIZ]; 
 int32_t    notify_type; 
 int32_t    type; 
 int32_t    status; 
 SLIST_ENTRY(target_notify) tn; 
};

この構造体は、Notification Tag エントリを表します - SNMP 通知は、この構造体の指定されたタグにマッチするタグがある Management Target Address リストの各エントリのための Target アドレスに送信されます。

デーモンは、Management Target グループリストのエントリを作成も、削除もしません、リストを管理するために外部のロード可能な (複数の) モジュールへのインタフェースを与えます。 target_new_address() は、ターゲットアドレスエントリを追加し、 target_delete_address() は、ターゲットアドレスリストから既存のエントリを削除します。 target_activate_address() は、実際にそのターゲットアドレスに SNMP 通知を送信することができるように、ターゲットアドレスエントリに関連付けられたソケットを作成します。 target_first_address() は、リストの最初のターゲットアドレスエントリへのポインタを返し、一方 target_next_address() は、与えられたエントリが存在しているなら、与えられたエントリの次のターゲットアドレスへのポインタを返します。 target_new_param() は、ターゲットパラメータのエントリを追加し、 target_delete_param() は、ターゲットパラメータリストから既存のエントリを削除します。 target_first_param() は、リストの最初のターゲットパラメータのエントリへのポインタを返し、一方 target_next_param() は、与えられたエントリが存在しているなら、与えられたエントリの次のターゲットパラメータへのポインタを返します。 target_new_notify() は、通知ターゲットエントリを追加し、 target_delete_notify() は、通知ターゲットリストから既存のエントリを削除します。 target_first_notify() は、リストの最初の通知ターゲットエントリへのポインタを返し、 target_next_notify() は、与えられたエントリが存在しているなら、与えられたエントリの次の通知ターゲットへのポインタを返します。 target_flush_all() は、3 つのグローバルな Management Target Group リストからすべての設定されたデータを削除するために使用されます。

よく知られている OID

グローバル変数 oid_zeroDotZero は、OID 0.0 を含んでいます。グローバル変数 oid_usmUnknownEngineIDs oid_usmNotInTimeWindows は、SNMPv3 USM Engine Discovery で使用される OID 1.3.6.1.6.3.15.1.1.4.0 と 1.3.6.1.6.3.15.1.1.2.0 を含んでいます。

ID 範囲の要求

SNMP エージェント関数のほかに SNMP クライアント関数を実装するモジュールでは、正しいサブシステムへの応答の、より簡単な経路制御を可能とするためにそれらの識別子によって SNMP 要求を識別する必要があるかもしれません。要求 ID 範囲は、全体の 31 ビット ID 範囲のグローバルに重ならないサブ範囲を獲得する方法を提供します。

要求 ID 範囲は、 reqid_allocate() で割り付けられます。引数は、次の通りです: 範囲のサイズとモジュール割り付け範囲。例えば、次の呼び出し

id = reqid_allocate(1000, module);

は、1000 の要求された ID を割り付けます。関数は、要求 ID 範囲識別子か、または十分な識別子の空間がなければ、0 を返します。関数 reqid_base() は、与えられた範囲で最も小さい要求 ID を返します。

要求 ID は、直線的なすべての範囲で最も小さいもので始まるように割り付けられます。クライアントアプリケーションに多くの未解決の要求があるかもしれないなら、範囲は、十分大きくなければならないので、 ID は、それが本当に期限が切れるまで、再利用されません。 reqid_next() は、範囲中で連続している次の ID を返します。

関数 reqid_istype() は、要求 ID reqidtype によって識別される範囲内にあるかどうかチェックします。関数 reqid_type() は、与えられた reqid のための範囲識別子を返し、要求 ID が範囲内にないなら、0 を返します。

タイマ

SNMP デーモンは、SNMP チック精度で任意の数のタイマをサポートします。関数 timer_start() は、 ticks SNMP チックの期限が切れた後、引数 uarg で呼び出されるコールバック func の準備をします。 mod は、タイマを始動するモジュールです。これらのタイマは、1 回限りで、それらは、再始動されません。繰り返し可能なタイマは、追加引数 repeat_ticks を取る timer_start_repeat() で始動されます。引数 ticks にはコールバックの最初の実行まで刻の数を与えます、一方 repeat_ticks は、コールバックの呼び出しの間の刻の数です。現在の初期の刻の数は、コールバックの呼び出しの間の刻の数と同じに黙って設定されることに注意してください。関数は、 timer_stop() を通してタイマを停止するために使用することができるタイマ識別子を返します。モジュールがアンロードされるなら、まだ期限が切れていないモジュールによって始動されたすべてのタイマが停止されます。

ファイル記述子サポート

モジュールは、ソケットファイル記述子からデーモン (例えば代替の SNMP 転送を実装する) をブロックしないで入力を得る必要があるかもしれません。

関数 fd_select() は、ファイル記述子 fd が読み込むことができるか、またはクローズ状態であるときはいつも、ファイル記述子 fd とユーザ引数 uarg で、コールバック関数 func が呼び出されるようにします。ファイル記述子が非ブロッキングモードでないなら、それは、非ブロッキングモードに設定されます。コールバックがそれ以上必要でないなら、 fd_deselect() は、 fd_select() から返される値で呼び出されます。モジュールによって選択されたすべてのファイル記述子は、モジュールがアンロードされるとき、自動的に選択が解除されます。

ファイル記述子登録を一次的にサスペンドするために、 fd_suspend() を呼び出すことができます。また、これは、 fd_select() への呼び出しの前にブロックしていたなら、ファイル記述子を元のブロッキングモードに戻らせます。これは、選択されたソケットで同期入力をする必要があります。 fd_suspend() の効果は、 fd_resume() で元に戻すことができます。

オブジェクトリソース

システムグループは、オブジェクトリソーステーブルを含みます。モジュールは、登録されるための oidstr のテキスト形式の記述、とモジュール mod へのポインタで or_register() を呼び出すことによってこのテーブルにエントリを作成します。登録は、 or_unregister() で取り除くことができます。すべてのモジュールの登録は、モジュールがアンロードされるなら、自動的に取り除かれます。

送信と受信バッファ

バッファは、 buf_alloc() を通して割り付けられます。引数は、転送のためには、 1、受信バッファのためには、0 でなければなりません。関数は、利用可能なメモリがなければ、 NULL を返します。現在のバッファサイズは、 buf_size() で取得することができます。

PDU の処理

それら自体の PDU 処理 (例えば、プロキシするための) を行う必要があるモジュールのためには、次の関数が利用可能です:

関数 snmp_input_start() は、PDU をデコードし、コミュニティを検索し、そして、グローバルの this_tick を設定します。次のエラーコードの 1 つを返します:

SNMPD_INPUT_OK
すべてうまくいきました、処理を続行します。
SNMPD_INPUT_FAILED
PDU は、デコードすることができないで、誤ったバージョンか未知のコミュニティ文字列があります。
SNMPD_INPUT_VALBADLEN
SET PDU に ASN.1 ヘッダに、誤った長さのフィールドでバインドされている値フィールドがあります。
SNMPD_INPUT_VALRANGE
SET PDU に与えられた ASN.1 タイプで範囲外の値でバインドされている値フィールドがあります。
SNMPD_INPUT_VALBADENC
SET PDU に誤った ASN.1 エンコードでバインドされている値フィールドがあります。
SNMPD_INPUT_TRUNC
バッファが有効に始まる PDU を含むために現れますが、短過ぎます。ストリーミング転送のために、呼び出し側が、呼び出し側が既に持っているものを保存し、より多くの入力を獲得することを試み、関数にこの入力を再発行しなければならないことを意味します。データグラム転送のために、データグラムの一部が失われて、入力が無視されるべきであることを意味します。

関数 snmp_input_finish() は、処理の残りの半分を行います: snmp_input_start() が OK を返さなかったなら、エラー応答を構成することを試みます。開始が OK であったなら、要求を実行するために bsnmpagent(3) から正しい関数を呼び出し、応答を構成した結果またはエラー応答 PDU によって、要求 PDU を無視します。それは、 SNMPD_INPUT_OKSNMPD_INPUT_FAILED のいずれかを返します。前者の場合には、応答 PDU が構築されて、送信されるべきです。

関数 snmp_output() は、PDU を取って、それをエンコードします。

関数 snmp_send_port() は、PDU を取って、それをコード化し、 (ポートテーブルの転送とインデックスによって識別される) 与えられたポートを通してそれを与えられたアドレスに送信します。

関数 snmp_send_trap() は、すべてのトラップ宛先 (終点) にトラップを送信します。引数は、トラップを識別する oid であり、リストにバインドされたトラップに挿入される struct snmp_value ポインタの NULL で終了したリストです。 snmp_pdu_auth_access() は、設定された View ベースの Access 規則に従って、許可されるか、拒否されるべきである、 pdu に含まれたオブジェクト ID へのアクセスされるかどうかを検証します。 ip は、どのアクセスが拒否される最初の varbinding のインデックスか、または PDU のすべての varbindings へのアクセスが許可されるなら、0 を含みます。訳注: varbinding の意味不明。

単純アクションサポート

依存関係が必要ない簡単なスカラ変数のために、多くのサポート関数は、set, commit, rollback と get の操作が利用可能です。

次の関数は、OCTET STRING スカラ、ヌル文字で終了、またはそれ以外のいずれかで使用されます:

string_save()
SNMP_OP_SET のために呼び出されるべきです。それぞれ valuectx は、ノードコールバックへの引数です。 valp は、現在の値を保持するポインタへのポインタです、 req_size は、文字列のどんなサイズも受け入れ可能なら -1、またはより大きな数、または文字列が指定されたサイズでなければならないなら、0 に等しくなるべきです。関数は、スクラッチ領域に古い値を保存し (いずれの初期値も malloc(3) によって割り付けられなければならないことに注意)、新しい文字列を割り付け、新しい値でコピーし、それをヌル文字で終了し、新しい現在の値に設定します。
string_commit()
スクラッチ領域に保存された古い値を単に解放します。
string_rollback()
新しい値を解放して、古いものに戻します。
string_get()
GET または GETNEXT で使用されます。
string_get_max()
返された文字列には、ある最大の長さがあることを保証するために string_get() の代わりに、この関数を使用することができます。 len が -1 であるなら、長さは、現在の文字列値から strlen(3) を使って計算されます。現在の値が NULL であるなら、長さ 0 の OCTET STRING が返されます。
string_free()
rollback または commit のいずれかが保存された古い値の解放に失敗するなら、呼び出されなければなりません。

次の関数は、タイプ IP アドレスのスカラを処理するために使用されます:

ip_save()
スクラッチ領域に現在の値を保存し、 valp から新しい値を設定します。
ip_commit()
何もしません。
ip_rollback()
スクラッチ領域からの古い IP アドレスを復元します。
ip_get()
現在の IP アドレスを検索します。

次の関数は、OID タイプの変数を取り扱います:

oid_save()
malloc(3)struct asn_oid を割り付けることによって、スクラッチ領域に現在の値を保存し、 oid から新しい値を設定します。
oid_commit()
スクラッチ領域の古い値を解放します。
oid_rollback()
スクラッチ領域から古い OID を復元して、古い OID を解放します。
oid_get()
OID を検索します。

テーブルインデックス操作

次の関数は、取り扱いテーブルインデックスで役立ちます:
index_decode()
OID のインデックス部分をデコードします。パラメータ oid は、ノードコールバックの value 引数の var フィールドへのポインタでなければなりません。 sub 引数は、OID のインデックスの始まりのインデックスでなければなりません (これは、ノードコールバックへの sub 引数です)。 code は、インデックス式 (ノードコールバックへのパラメータ idx) です。これらのパラメータには、次のようなインデックス要素の構文に依存するパラメータが続きます:
INTEGER
引数として int32_t * を期待します。
COUNTER64
引数として uint64_t * を期待します。この構文は、インデックスは、不正であることに注意してください。
OCTET STRING
引数として u_char **size_t * を期待します。バッファは、デコードされた文字列を保持するために割り付けられます。
OID
引数として struct asn_oid * を期待します。
IP ADDRESS
少なくとも 4 バイトのバッファを指す引数として u_int8_t * を期待します。
COUNTER, GAUGE, TIMETICKS
u_int32_t を期待します。
NULL
引数は、期待されません。
index_compare()
OID と現在の変数を比較しす。 oid1sub は、それぞれノードのコールバック引数 value->varsub から来ます。 oid2 は、比較するための OID です。関数は、変数が与えられた OID より少なく、等しく、大きいときに、-1、0、+1 を返します。 oid2 は、テーブルカラムのインデックス部分だけを含まなければなりません。
index_compare_off()
両方のインデックスの最初の off 構成要素を無視させる追加パラメータ off を取ることを除いて、 index_compare() と同等です。
index_append()
位置 sub で始まる OID srcdst に追加します。
index_append_off()
位置 off で始まる OID src を位置 sub + off で始まる dst に追加します。

規格

この実装は、適切な IETF RFC と ITU-T 勧告に適合しています。

作者

Hartmut Brandt <harti@FreeBSD.org>
December 19, 2010 FreeBSD