OSDN Git Service

ソースツリー再構成中(ほぼOK?)
[ultramonkey-l7/ultramonkey-l7-v3.git] / l7vsd / src / snmpbridge.cpp
1 /*!
2  * @file  snmpbridge.cpp
3  * @brief snmpagent connection module.
4  *
5  * L7VSD: Linux Virtual Server for Layer7 Load Balancing
6  * Copyright (C) 2009  NTT COMWARE Corporation.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  *
23  **********************************************************************/
24 #include <map>
25 #include <vector>
26 #include <boost/lexical_cast.hpp>
27 //#include <sys/socket.h>
28 //#include <sys/types.h>
29 //#include <unistd.h>
30 //#include <netdb.h>
31 #include <string.h>
32 #include <error.h>
33 #include "realserver_element.h"
34 #include "realserver.h"
35 #include "virtualservice_element.h"
36 #include "virtualservice.h"
37 #include "snmpbridge.h"
38 #include "logger.h"
39 #include "parameter.h"
40 #include "../snmpagent/message.h"
41
42 /*!
43  * initialize function
44  * @return  int  0 is nomal end not 0 is abnomal end
45  */
46 int l7vs::snmpbridge::initialize(){
47         Logger logger( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 1, "initialize", __FILE__, __LINE__ );
48
49         int retval =  0;
50         //cleate log level table
51         snmp_loglevel_map.clear();
52         snmp_loglevel_map.insert( std::pair<l7vs::LOG_CATEGORY_TAG,std::string>( LOG_CAT_SNMPAGENT_START_STOP, "snmpagent_start_stop" ) );
53         snmp_loglevel_map.insert( std::pair<l7vs::LOG_CATEGORY_TAG,std::string>( LOG_CAT_SNMPAGENT_MANAGER_RECEIVE, "snmpagent_manager_receive" ) );
54         snmp_loglevel_map.insert( std::pair<l7vs::LOG_CATEGORY_TAG,std::string>( LOG_CAT_SNMPAGENT_MANAGER_SEND, "snmpagent_manager_send" ) );
55         snmp_loglevel_map.insert( std::pair<l7vs::LOG_CATEGORY_TAG,std::string>( LOG_CAT_SNMPAGENT_L7VSD_RECEIVE, "snmpagent_l7vsd_receive" ) );
56         snmp_loglevel_map.insert( std::pair<l7vs::LOG_CATEGORY_TAG,std::string>( LOG_CAT_SNMPAGENT_L7VSD_SEND, "snmpagent_l7vsd_send" ) );
57         snmp_loglevel_map.insert( std::pair<l7vs::LOG_CATEGORY_TAG,std::string>( LOG_CAT_SNMPAGENT_LOGGER, "snmpagent_logger" ) );
58         snmp_loglevel_map.insert( std::pair<l7vs::LOG_CATEGORY_TAG,std::string>( LOG_CAT_SNMPAGENT_PARAMETER, "snmpagent_parameter" ) );
59         snmp_loglevel_map.insert( std::pair<l7vs::LOG_CATEGORY_TAG,std::string>( LOG_CAT_SNMPAGENT_SYSTEM, "snmpagent_system" ) );
60         snmp_loglevel_map.insert( std::pair<l7vs::LOG_CATEGORY_TAG,std::string>( LOG_CAT_SNMPAGENT_SYSTEM_MEMORY, "snmpagent_system_memory" ) );
61         snmp_loglevel_map.insert( std::pair<l7vs::LOG_CATEGORY_TAG,std::string>( LOG_CAT_SNMPAGENT_SYSTEM_ENDPOINT, "snmpagent_system_endpoint" ) );
62         snmp_loglevel_map.insert( std::pair<l7vs::LOG_CATEGORY_TAG,std::string>( LOG_CAT_SNMPAGENT_SYSTEM_SIGNAL, "snmpagent_system_signal" ) );
63         snmp_loglevel_map.insert( std::pair<l7vs::LOG_CATEGORY_TAG,std::string>( LOG_CAT_SNMPAGENT_SYSTEM_ENVIRONMENT, "snmpagent_system_environment" ) );
64
65         levelstring_map.clear();
66         levelstring_map.insert( std::pair<std::string,l7vs::LOG_LEVEL_TAG>("debug",LOG_LV_DEBUG) );
67         levelstring_map.insert( std::pair<std::string,l7vs::LOG_LEVEL_TAG>("info",LOG_LV_INFO) );
68         levelstring_map.insert( std::pair<std::string,l7vs::LOG_LEVEL_TAG>("warn",LOG_LV_WARN) );
69         levelstring_map.insert( std::pair<std::string,l7vs::LOG_LEVEL_TAG>("error",LOG_LV_ERROR) );
70         levelstring_map.insert( std::pair<std::string,l7vs::LOG_LEVEL_TAG>("fatal",LOG_LV_FATAL) );
71
72         if( load_config() != 0 ) return -1;//don't read config
73
74         if( snmp_acceptor.is_open() == false ){
75                 boost::asio::ip::tcp::endpoint recv_endpoint( boost::asio::ip::address::from_string(snmp_param.address), snmp_param.portno );
76                 snmp_acceptor.open( recv_endpoint.protocol() );
77                 snmp_acceptor.set_option( boost::asio::socket_base::reuse_address(true) );
78                 snmp_acceptor.bind( recv_endpoint );
79                 snmp_acceptor.listen();
80                 snmp_acceptor.async_accept( snmp_socket, boost::bind( &snmpbridge::handle_accept, this, boost::asio::placeholders::error ) );
81         }
82         return retval;
83 }
84
85 /*!
86  * finalize function
87  * @param[in]
88  * @return
89  */
90 void l7vs::snmpbridge::finalize(){
91         Logger logger( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 2, "finalize", __FILE__, __LINE__ );
92
93         connection_state = false;
94         snmp_acceptor.close();
95         snmp_socket.close();
96         if( !send_buffer ){
97                 free(send_buffer);
98                 send_buffer      = NULL;
99                 send_buffer_size = 0;
100         }
101 }
102
103 /*!
104  * TRAP Request send
105  * @param[in]   *message   Trap message
106  * @return      int
107  */
108 int l7vs::snmpbridge::send_trap( const std::string& message ){
109         Logger logger( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 3, "send_trap", __FILE__, __LINE__ );
110
111         if( connection_state == false ){
112                 std::string msg( "snmpbridge is disconnect" );
113                 Logger::putLogError( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 1, msg, __FILE__, __LINE__ );
114                 return -1;
115         }
116
117         boost::mutex::scoped_lock lock( send_buffer_mutex );
118
119         if( send_buffer ) free( send_buffer );
120         send_buffer_size = sizeof( struct l7ag_message_header ) +
121                                 sizeof( struct l7ag_payload_header ) +
122                                 sizeof( struct l7ag_traprequest_message );
123         send_buffer = (char*) calloc( 1, send_buffer_size );
124         if( !send_buffer ){
125                 //malloc error!
126                 std::string msg( "send buffer malloc error" );
127                 Logger::putLogError( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 2, msg, __FILE__, __LINE__ );
128                 return -1;
129         }
130         struct l7ag_message_header* header        = (struct l7ag_message_header*) send_buffer;
131         struct l7ag_payload_header* payloadheader = (struct l7ag_payload_header*) (header + 1);
132         struct l7ag_traprequest_message* trapmes  = (struct l7ag_traprequest_message*) (payloadheader + 1);
133
134         //create message header
135         header->magic[0] = 0x4d;    // M
136         header->magic[1] = 0x47;    // G
137         header->version = 1;
138         time_t  tim;
139         time( &tim );
140         header->time = ( unsigned long long ) tim;
141         header->payload_count = 1;
142         header->size = send_buffer_size;
143
144         //create payload header
145         payloadheader->magic[0] = 0x50; // P
146         payloadheader->magic[1] = 0x59; // Y
147         payloadheader->message_id = MESSAGE_ID_TRAPREQUEST;
148         payloadheader->payload_datasize = sizeof( struct l7ag_payload_header ) + sizeof( struct l7ag_traprequest_message );
149
150         //create message
151         char oid[] = "1.3.6.1.4.1.60000.1.0.2";
152         strncpy( trapmes->oid, oid , sizeof( oid ) );
153         strncpy( trapmes->message, message.c_str(), TRAPREQUESTMESSAGESIZE );
154         trapmes->magic[0] = 0x54;   // T
155         trapmes->magic[1] = 0x52;   // R
156
157         // register iom (send)
158         if (send_message() != 0) {
159                 free(send_buffer);
160                 send_buffer      = NULL;
161                 send_buffer_size = 0;
162                 return -1;
163         }
164         return 0;
165 }
166
167 /*!
168  * Reload config command to subagent
169  */
170 void l7vs::snmpbridge::reload_config(){
171         Logger logger( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 4, "reload_config", __FILE__, __LINE__ );
172
173         boost::mutex::scoped_lock lock( send_buffer_mutex );
174
175         if( send_buffer ) free( send_buffer );
176         send_buffer_size = sizeof( struct l7ag_message_header ) +
177                                 sizeof( struct l7ag_payload_header ) +
178                                 sizeof( struct l7ag_settingcommand_message );
179
180         send_buffer = (char*) calloc( 1, send_buffer_size );
181         if( !send_buffer ){
182                 //malloc error!
183                 std::string msg( "send buffer malloc error" );
184                 Logger::putLogError( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 3, msg, __FILE__, __LINE__ );
185                 return;
186         }
187         struct l7ag_message_header* header             = (struct l7ag_message_header*) send_buffer;
188         struct l7ag_payload_header* payloadheader      = (struct l7ag_payload_header*) (header + 1);
189         struct l7ag_settingcommand_message* settingcmd = (struct l7ag_settingcommand_message*) (payloadheader + 1);
190         //create message header
191         header->magic[0] = 0x4d;    // M
192         header->magic[1] = 0x47;    // G
193         header->version = 1;
194         time_t  tim;
195         time( &tim );
196         header->time = ( unsigned long long ) tim;
197         header->payload_count = 1;
198         header->size = send_buffer_size;
199
200         //create payload header
201         payloadheader->magic[0] = 0x50; // P
202         payloadheader->magic[1] = 0x59; // Y
203         payloadheader->message_id = MESSAGE_ID_COMMANDREQUEST;
204         payloadheader->payload_datasize = sizeof( struct l7ag_payload_header ) + sizeof( struct l7ag_settingcommand_message );
205
206         //create settingcommand_message
207         settingcmd->command_id = COMMAND_SETTINGFILE_RELOAD;
208         memset( settingcmd->data, 0, COMMANDDATASIZE );
209         settingcmd->magic[0] = 0x53;    // S
210         settingcmd->magic[1] = 0x54;    // T
211
212         // register iom (send)
213         if(send_message() != 0 ){
214                 free(send_buffer);
215                 send_buffer      = NULL;
216                 send_buffer_size = 0;
217         }
218         load_config();
219 }
220
221 /*!
222  * Set log level command to subagent
223  */
224 int l7vs::snmpbridge::change_loglevel( const l7vs::LOG_CATEGORY_TAG snmp_log_category, const l7vs::LOG_LEVEL_TAG loglevel ){
225         Logger logger( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 5, "change_loglevel", __FILE__, __LINE__ );
226
227         int retval = 0;
228         if( snmp_param.loglevel.end() != snmp_param.loglevel.find( snmp_log_category ) ){
229                 boost::mutex::scoped_lock lock( send_buffer_mutex );
230
231                 if( send_buffer ) free( send_buffer );
232                 send_buffer_size = sizeof( struct l7ag_message_header ) +
233                         sizeof( struct l7ag_payload_header ) +
234                         sizeof( struct l7ag_settingcommand_message );
235
236                 send_buffer = (char*) calloc( 1, send_buffer_size );
237                 if( !send_buffer ){
238                         //malloc error!
239                         std::string msg( "send buffer malloc error" );
240                         Logger::putLogError( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 4, msg, __FILE__, __LINE__ );
241                         return -1;
242                 }
243                 struct l7ag_message_header* header             = (struct l7ag_message_header*) send_buffer;
244                 struct l7ag_payload_header* payloadheader      = (struct l7ag_payload_header*) (header + 1);
245                 struct l7ag_settingcommand_message* settingcmd = (struct l7ag_settingcommand_message*) (payloadheader + 1);
246                 struct l7ag_changeloglevel_parameter* param    = (struct l7ag_changeloglevel_parameter*) settingcmd->data;
247                 //create message header
248                 header->magic[0] = 0x4d;    // M
249                 header->magic[1] = 0x47;    // G
250                 header->version = 1;
251                 time_t  tim;
252                 time( &tim );
253                 header->time = ( unsigned long long ) tim;
254                 header->payload_count = 1;
255                 header->size = send_buffer_size;
256
257                 //create payload header
258                 payloadheader->magic[0] = 0x50; // P
259                 payloadheader->magic[1] = 0x59; // Y
260                 payloadheader->message_id = MESSAGE_ID_COMMANDREQUEST;
261                 payloadheader->payload_datasize = sizeof( struct l7ag_payload_header ) + sizeof( struct l7ag_settingcommand_message);
262
263                 //create settingcmd
264                 settingcmd->command_id  = COMMAND_LOGLEVEL_CHANGE;
265                 settingcmd->magic[0]    = 0x4c;    // L
266                 settingcmd->magic[1]    = 0x4c;    // L
267                 //create log level
268                 param->log_category = snmp_log_category;
269                 param->log_level = loglevel;
270
271                 // register iom (send)
272                 retval = send_message();
273                 if( retval != 0 ){
274                         free(send_buffer);
275                         send_buffer      = NULL;
276                         send_buffer_size = 0;
277                 }else{
278                         snmp_param.loglevel.find( snmp_log_category )->second = loglevel;
279                 }
280         }else{
281                 retval = -1;
282         }
283         return retval;
284 }
285
286 /*!
287  * Set all log level command to subagent
288  */
289 int l7vs::snmpbridge::change_loglevel_allcategory( const l7vs::LOG_LEVEL_TAG loglevel ){
290         Logger logger( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 6, "change_loglevel_allcategory", __FILE__, __LINE__ );
291
292         int retval = 0;
293         std::vector<struct l7ag_settingcommand_message> settingcmd_vec;
294         for( std::map<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>::iterator it = snmp_param.loglevel.begin();
295                 it != snmp_param.loglevel.end(); ++it ){
296
297                 struct l7ag_settingcommand_message cmd;
298                 cmd.command_id = COMMAND_LOGLEVEL_CHANGE;
299                 struct l7ag_changeloglevel_parameter* param = (l7ag_changeloglevel_parameter*) cmd.data;
300                 param->log_category = it->first;
301                 param->log_level = loglevel;
302                 settingcmd_vec.push_back( cmd );
303         }
304         boost::mutex::scoped_lock lock( send_buffer_mutex );
305
306         if( send_buffer ) free( send_buffer );
307         send_buffer_size = sizeof( struct l7ag_message_header ) +
308                                 sizeof( struct l7ag_payload_header ) * settingcmd_vec.size() +
309                                 sizeof( struct l7ag_settingcommand_message ) * settingcmd_vec.size();
310         send_buffer = (char*) calloc( 1, send_buffer_size );
311         if( !send_buffer ){
312                 //malloc error!
313                 std::string msg( "send buffer malloc error" );
314                 Logger::putLogError( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 5, msg, __FILE__, __LINE__ );
315                 return -1;
316         }
317         struct l7ag_message_header* header = (struct l7ag_message_header*) send_buffer;
318         struct l7ag_payload_header* payloadheader = (struct l7ag_payload_header*) (header + 1);
319         struct l7ag_settingcommand_message* settingcmd = (struct l7ag_settingcommand_message*) (payloadheader + 1);
320         //create message header
321         header->magic[0] = 0x4d;    // M
322         header->magic[1] = 0x47;    // G
323         header->version = 1;
324         time_t tim;
325         time( &tim );
326         header->time = ( unsigned long long ) tim;
327         header->payload_count = settingcmd_vec.size();
328         header->size = send_buffer_size;
329
330         //datas
331         for( std::vector<struct l7ag_settingcommand_message>::iterator itr = settingcmd_vec.begin();
332                 itr != settingcmd_vec.end(); ++itr ){
333
334                 payloadheader->magic[0] = 0x50; // P
335                 payloadheader->magic[1] = 0x59; // Y
336                 payloadheader->message_id = MESSAGE_ID_COMMANDREQUEST;
337                 payloadheader->payload_datasize = sizeof( struct l7ag_payload_header ) + sizeof( struct l7ag_settingcommand_message );
338                 settingcmd->command_id  = COMMAND_LOGLEVEL_CHANGE;
339                 settingcmd->magic[0]    = 0x4c;    // L
340                 settingcmd->magic[1]    = 0x4c;    // L
341                 memcpy( settingcmd->data, &(*itr), sizeof( struct l7ag_changeloglevel_parameter) );
342                 payloadheader = (struct l7ag_payload_header*) (settingcmd + 1);
343                 settingcmd = (struct l7ag_settingcommand_message*) (payloadheader + 1);
344         }
345
346         // register iom (send)
347         retval = send_message();
348         if( retval != 0 ){
349                 free(send_buffer);
350                 send_buffer      = NULL;
351                 send_buffer_size = 0;
352         }else{
353                 for( std::map<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>::iterator it = snmp_param.loglevel.begin();
354                         it != snmp_param.loglevel.end(); ++it ){
355
356                         it->second = loglevel;
357                 }
358         }
359         return retval;
360 }
361
362 /*!
363  * Send all MIB data
364  */
365 int l7vs::snmpbridge::send_mibcollection(struct l7ag_mibrequest_message* payload){
366         Logger logger( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 7, "send_mibcollection", __FILE__, __LINE__ );
367
368         if( connection_state == false ){
369                 std::string msg( "snmpbridge is disconnect" );
370                 Logger::putLogError( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 6, msg, __FILE__, __LINE__ );
371                 return -1;
372         }
373
374         int retval = 0;
375         boost::mutex::scoped_lock lock( send_buffer_mutex );
376
377         if (send_buffer) {
378                 free(send_buffer);
379                 send_buffer = NULL;
380                 send_buffer_size = 0;
381         }
382
383         // TODO should check payload oid and return specified MIB data only.
384
385         boost::mutex& virtualservice_list_mutex = vsd.get_virtualservice_list_mutex();
386         boost::mutex::scoped_lock list_lock( virtualservice_list_mutex );
387         std::list< boost::shared_ptr< virtual_service > >& virtualservice_list = vsd.get_virtualservice_list();
388
389         int real_servers = 0;
390         for(std::list< boost::shared_ptr< virtual_service > >::iterator it = virtualservice_list.begin();
391                 it != virtualservice_list.end(); it++ ){
392
393                 virtualservice_element& element = (*it)->get_element();
394                 real_servers += element.realserver_vector.size();
395         }
396         int payload_vs_count = 1;
397         if (virtualservice_list.size() > 1) {
398                 payload_vs_count = virtualservice_list.size();
399         }
400         int payload_rs_count = 1;
401         if (real_servers > 1) {
402                 payload_rs_count = real_servers;
403         }
404         send_buffer_size = sizeof( struct l7ag_message_header ) +
405                                  ( sizeof( struct l7ag_payload_header ) + sizeof( struct l7ag_mibdata_payload_vs ) ) * payload_vs_count +
406                                  ( sizeof( struct l7ag_payload_header ) + sizeof( struct l7ag_mibdata_payload_rs ) ) * payload_rs_count;
407
408         send_buffer = (char*) calloc( 1, send_buffer_size );
409         if( !send_buffer ){
410                 //malloc error!
411                 std::string msg( "send buffer malloc error" );
412                 Logger::putLogError( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 7, msg, __FILE__, __LINE__ );
413                 return -1;
414         }
415         struct l7ag_message_header* header = (struct l7ag_message_header*) send_buffer;
416
417         //create message header
418         header->magic[0] = 0x4d;    // M
419         header->magic[1] = 0x47;    // G
420         header->version = 1;
421         time_t tim;
422         time( &tim );
423         header->time = ( unsigned long long ) tim;
424         header->payload_count = payload_vs_count + payload_rs_count;
425         header->size = send_buffer_size;
426
427         //create payload header
428         void* pos = (void *) (header + 1);
429         int vs_counter = 1;
430         int rs_counter = 1;
431
432         for(std::list< boost::shared_ptr< virtual_service > >::iterator vs_it = virtualservice_list.begin();
433                 vs_it != virtualservice_list.end(); vs_it++ ){
434
435                 struct l7ag_payload_header* payloadheader = (struct l7ag_payload_header*) pos;
436                 payloadheader->magic[0] = 0x50; // P
437                 payloadheader->magic[1] = 0x59; // Y
438                 payloadheader->message_id = MESSAGE_ID_MIBCOLLECTRESPONSE_VS;
439                 payloadheader->payload_datasize = sizeof(struct l7ag_payload_header) + sizeof(struct l7ag_mibdata_payload_vs);
440                 pos = payloadheader + 1;
441
442                 struct l7ag_mibdata_payload_vs* vs = (struct l7ag_mibdata_payload_vs*) pos;
443                 vs->magic[0]    = 0x56; // V
444                 vs->magic[1]    = 0x53; // S
445                 vs->index               = vs_counter;
446                 virtualservice_element& srv = (*vs_it)->get_element();
447                 if(srv.udpmode){
448                         vs->protocol            = IPPROTO_UDP;
449                         if( srv.udp_recv_endpoint.address().is_v4() ){
450                                 vs->ipAddress       = srv.udp_recv_endpoint.address().to_v4().to_ulong();//
451                         }
452                         vs->portNumber          = srv.udp_recv_endpoint.port();
453                 }else{
454                         vs->protocol            = IPPROTO_TCP;
455                         if( srv.tcp_accept_endpoint.address().is_v4() ){
456                                 vs->ipAddress       = srv.tcp_accept_endpoint.address().to_v4().to_ulong();//
457                         }
458                         vs->portNumber          = srv.tcp_accept_endpoint.port();
459                 }
460                 vs->reschedule          = 0;//
461                 if( srv.sorry_endpoint.address().is_v4() ){
462                         vs->sorryIpAddress      = srv.sorry_endpoint.address().to_v4().to_ulong();//
463                 }
464                 vs->sorryPortNumber     = srv.sorry_endpoint.port();
465                 vs->sorryThreshold      = srv.sorry_maxconnection;
466                 vs->sorryForceFlag      = srv.sorry_flag;
467                 vs->QoSThresholdUp      = srv.qos_upstream;
468                 vs->QoSThresholdDown    = srv.qos_downstream;
469                 vs->throughputUp        = (*vs_it)->get_throughput_upstream();
470                 vs->throughputDown      = (*vs_it)->get_throughput_downstream();
471                 vs->vs_count            = payload_vs_count;
472                 strncpy(vs->scheduleModule, srv.schedule_module_name.c_str(), L7VS_MODNAME_LEN);
473                 strncpy(vs->protocolModule, srv.protocol_module_name.c_str(), L7VS_MODNAME_LEN);
474                 std::stringstream module_arg;
475                 for( std::vector<std::string>::iterator arg_it = srv.protocol_args.begin();
476                         arg_it != srv.protocol_args.end(); arg_it++ ){
477
478                         module_arg << *arg_it << " ";
479                 }
480                 std::string module_option;
481                 module_arg >> module_option;
482                 strncpy(vs->protocolModuleOption, module_option.c_str(), L7VS_PROTOMOD_OPT_LEN);
483
484                 pos = vs + 1;
485
486                 int rs_count = srv.realserver_vector.size();
487                 if (rs_count > 0) {
488                         for( std::vector<realserver_element>::iterator rs_it = srv.realserver_vector.begin();
489                                 rs_it != srv.realserver_vector.end(); rs_it++ ){
490
491                                 payloadheader = (struct l7ag_payload_header*) pos;
492                                 payloadheader->magic[0] = 0x50; // P
493                                 payloadheader->magic[1] = 0x59; // Y
494                                 payloadheader->message_id = MESSAGE_ID_MIBCOLLECTRESPONSE_RS;
495                                 payloadheader->payload_datasize = sizeof(struct l7ag_payload_header) + sizeof(struct l7ag_mibdata_payload_rs);
496                                 pos = payloadheader + 1;
497
498                                 struct l7ag_mibdata_payload_rs* rs = (struct l7ag_mibdata_payload_rs*) pos;
499                                 rs->magic[0]            = 0x52; // R
500                                 rs->magic[1]            = 0x53; // S
501                                 rs->index               = rs_counter;
502                                 rs->virtualServiceIndex = vs_counter;
503                                 realserver_element& dest = *rs_it;
504                                 if(srv.udpmode){
505                                         if( dest.udp_endpoint.address().is_v4() ){
506                                                 rs->ipAddress       = dest.udp_endpoint.address().to_v4().to_ulong();//
507                                         }
508                                         rs->portNumber      = dest.udp_endpoint.port();
509                                 }else{
510                                         if( dest.tcp_endpoint.address().is_v4() ){
511                                                 rs->ipAddress       = dest.tcp_endpoint.address().to_v4().to_ulong();//
512                                         }
513                                         rs->portNumber      = dest.tcp_endpoint.port();
514                                 }
515                                 rs->forwardMode         = 1; // masq only
516                                 rs->weight              = dest.weight;
517                                 rs->activeConn          = dest.get_active();
518                                 rs->inactiveConn        = dest.get_inact();
519                                 rs->rs_count            = real_servers;
520                                 pos = rs + 1;
521
522                                 rs_counter++;
523                         }
524                 }
525                 vs_counter++;
526         }
527         // for clear vs table
528         if (virtualservice_list.size() == 0) {
529                 struct l7ag_payload_header* payloadheader = (struct l7ag_payload_header*) pos;
530                 payloadheader->magic[0] = 0x50; // P
531                 payloadheader->magic[1] = 0x59; // Y
532                 payloadheader->message_id = MESSAGE_ID_MIBCOLLECTRESPONSE_VS;
533                 payloadheader->payload_datasize = sizeof(struct l7ag_payload_header) + sizeof(struct l7ag_mibdata_payload_vs);
534                 pos = payloadheader + 1;
535                 struct l7ag_mibdata_payload_vs* vs = (struct l7ag_mibdata_payload_vs*) pos;
536                 vs->magic[0]    = 0x56; // V
537                 vs->magic[1]    = 0x53; // S
538                 vs->index       = 0;
539                 vs->vs_count    = 0;
540                 pos = vs + 1;
541         }
542         // for clear rs table
543         if (real_servers == 0) {
544                 struct l7ag_payload_header* payloadheader = (struct l7ag_payload_header*) pos;
545                 payloadheader->magic[0] = 0x50; // P
546                 payloadheader->magic[1] = 0x59; // Y
547                 payloadheader->message_id = MESSAGE_ID_MIBCOLLECTRESPONSE_VS;
548                 payloadheader->payload_datasize = sizeof(struct l7ag_payload_header) + sizeof(struct l7ag_mibdata_payload_vs);
549                 pos = payloadheader + 1;
550                 struct l7ag_mibdata_payload_rs* rs = (struct l7ag_mibdata_payload_rs*) pos;
551                 rs->magic[0]    = 0x52; // R
552                 rs->magic[1]    = 0x53; // S
553                 rs->index       = 0;
554                 rs->rs_count    = 0;
555                 pos = rs + 1;
556         }
557
558         // register iom (send)
559         retval = send_message();
560         if( retval != 0 ){
561                 free(send_buffer);
562                 send_buffer      = NULL;
563                 send_buffer_size = 0;
564         }
565         return retval;
566 }
567
568 /*!
569  * Get connection status
570  */
571 bool l7vs::snmpbridge::get_connectionstate(){
572         Logger logger( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 8, "get_connectionstate", __FILE__, __LINE__ );
573         return connection_state;
574 }
575
576 /*!
577  * Get log level
578  */
579 l7vs::LOG_LEVEL_TAG l7vs::snmpbridge::get_loglevel( const l7vs::LOG_CATEGORY_TAG snmp_log_category ){
580         Logger logger( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 9, "get_loglevel", __FILE__, __LINE__ );
581
582         l7vs::LOG_LEVEL_TAG level = LOG_LV_NONE;
583         if( snmp_param.loglevel.end() != snmp_param.loglevel.find( snmp_log_category ) ){
584                 level = snmp_param.loglevel.find( snmp_log_category )->second;
585         }
586         return level;
587 }
588
589 /*!
590  * Get log level allcategory
591  */
592 void l7vs::snmpbridge::get_loglevel_allcategory( std::map<l7vs::LOG_CATEGORY_TAG, l7vs::LOG_LEVEL_TAG>& loglevelmap ){
593         Logger logger( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 10, "get_loglevel_allcategory", __FILE__, __LINE__ );
594
595         for( std::map<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>::iterator it = snmp_param.loglevel.begin();
596                 it != snmp_param.loglevel.end(); ++it ){
597
598                 loglevelmap.insert( std::pair<l7vs::LOG_CATEGORY_TAG, l7vs::LOG_LEVEL_TAG>( it->first, it->second ) );
599         }
600 }
601
602 /*!
603  *
604  */
605 void l7vs::snmpbridge::handle_accept(const boost::system::error_code& error){
606         Logger logger( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 11, "handle_accept", __FILE__, __LINE__ );
607
608         connection_state = true;
609         snmp_socket.async_receive( boost::asio::buffer( recv_buffer, READBUF_SIZE ), 
610                                                                 boost::bind(&snmpbridge::handle_receive,
611                                                                 this,
612                                                                 boost::asio::placeholders::error,
613                                                                 boost::asio::placeholders::bytes_transferred ) );
614 }
615
616 /*!
617  *
618  */
619 void l7vs::snmpbridge::handle_receive(const boost::system::error_code& error, size_t bytes_transferred){
620         Logger logger( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 12, "handle_receive", __FILE__, __LINE__ );
621
622         struct l7ag_message_header* message_header = NULL;
623         struct l7ag_payload_header* payload_header = NULL;
624
625         if ( bytes_transferred < sizeof( l7ag_message_header ) ){
626                 snmp_socket.async_receive( boost::asio::buffer( recv_buffer, READBUF_SIZE ), 
627                                                                 boost::bind(&snmpbridge::handle_receive,
628                                                                 this,
629                                                                 boost::asio::placeholders::error,
630                                                                 boost::asio::placeholders::bytes_transferred ) );
631
632                 std::string msg( "receive data is short" );
633                 Logger::putLogError( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 8, msg, __FILE__, __LINE__ );
634                 return;
635         }
636         message_header = (struct l7ag_message_header*)recv_buffer.data();
637         if ( message_header->version != 1 ){
638                 snmp_socket.async_receive( boost::asio::buffer( recv_buffer, READBUF_SIZE ), 
639                                                                 boost::bind(&snmpbridge::handle_receive,
640                                                                 this,
641                                                                 boost::asio::placeholders::error,
642                                                                 boost::asio::placeholders::bytes_transferred ) );
643
644                 std::string msg( "message header version error" );
645                 Logger::putLogError( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 9, msg, __FILE__, __LINE__ );
646                 return;
647         }
648         if ( message_header->magic[0] != 0x4d || message_header->magic[1] != 0x47 ){
649                 snmp_socket.async_receive( boost::asio::buffer( recv_buffer, READBUF_SIZE ), 
650                                                                 boost::bind(&snmpbridge::handle_receive,
651                                                                 this,
652                                                                 boost::asio::placeholders::error,
653                                                                 boost::asio::placeholders::bytes_transferred ) );
654
655                 std::string msg( "message header magic number error" );
656                 Logger::putLogError( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 10, msg, __FILE__, __LINE__ );
657                 return;
658         }
659         for ( unsigned long long i = 0; i < message_header->payload_count; ++i ) {
660                 // TODO bug if payload_count = 2...
661                 payload_header = (struct l7ag_payload_header*) (message_header + 1);
662                 if (payload_header->magic[0] != 0x50 || payload_header->magic[1] != 0x59) {
663                         continue;
664                 }
665                 struct l7ag_mibrequest_message* payload = (struct l7ag_mibrequest_message*) (payload_header + 1);
666                 switch (payload_header->message_id) {
667                 case MESSAGE_ID_MIBCOLLECTREQUEST:
668                         if (payload->magic[0] != 0x52 || payload->magic[1] != 0x51) {
669                                 snmp_socket.async_receive( boost::asio::buffer( recv_buffer, READBUF_SIZE ), 
670                                                                 boost::bind(&snmpbridge::handle_receive,
671                                                                 this,
672                                                                 boost::asio::placeholders::error,
673                                                                 boost::asio::placeholders::bytes_transferred ) );
674
675                                 std::string msg( "payload magic number error" );
676                                 Logger::putLogError( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 11, msg, __FILE__, __LINE__ );
677                                 return;
678                         }
679                         send_mibcollection(payload);
680                         break;
681                 }
682         }
683         snmp_socket.async_receive( boost::asio::buffer( recv_buffer, READBUF_SIZE ), 
684                                                                 boost::bind(&snmpbridge::handle_receive,
685                                                                 this,
686                                                                 boost::asio::placeholders::error,
687                                                                 boost::asio::placeholders::bytes_transferred ) );
688 }
689
690 /*!
691  *
692  */
693 void l7vs::snmpbridge::handle_send(const boost::system::error_code& error, size_t bytes_transferred){
694         Logger logger( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 13, "handle_send", __FILE__, __LINE__ );
695
696         snmp_socket.async_receive( boost::asio::buffer( recv_buffer, READBUF_SIZE ), 
697                                                                 boost::bind(&snmpbridge::handle_receive,
698                                                                 this,
699                                                                 boost::asio::placeholders::error,
700                                                                 boost::asio::placeholders::bytes_transferred ) );
701 }
702
703 /*!
704  *
705  */
706 int l7vs::snmpbridge::send_message(){
707         Logger logger( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 14, "send_message", __FILE__, __LINE__ );
708
709         if( connection_state == false ){
710                 std::string msg( "snmpbridge is disconnect" );
711                 Logger::putLogError( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 12, msg, __FILE__, __LINE__ );
712                 return -1;
713         }
714
715         if (send_buffer == NULL || send_buffer_size == 0){
716                 std::string msg( "send data is none" );
717                 Logger::putLogError( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 13, msg, __FILE__, __LINE__ );
718                 return -1;
719         }
720         snmp_socket.async_send( boost::asio::buffer( send_buffer, send_buffer_size ), 
721                                                                 boost::bind(&snmpbridge::handle_send,
722                                                                 this,
723                                                                 boost::asio::placeholders::error,
724                                                                 boost::asio::placeholders::bytes_transferred ) );
725         return 0;
726 }
727
728 /*!
729  *
730  */
731 int l7vs::snmpbridge::load_config(){
732         Logger logger( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 15, "load_config", __FILE__, __LINE__ );
733
734         l7vs::Parameter param;
735         l7vs::error_code err;
736         int tmp_int;
737         std::string tmp_str;
738
739         // load port no from cf
740         tmp_str = param.get_string( l7vs::PARAM_COMP_SNMPAGENT, "nic", err );
741         if( !err ){
742                 snmp_param.nic = tmp_str;
743         }
744         else{
745                 snmp_param.nic = NIC_DEFAULT;
746                 err.setter( false, "" );
747         }
748         tmp_str = param.get_string( l7vs::PARAM_COMP_SNMPAGENT, "ip_addr", err );
749         if( !err ){
750                 snmp_param.address = tmp_str;
751         }
752         else{
753                 snmp_param.address = ADDR_DEFAULT;
754                 err.setter( false, "" );
755         }
756         tmp_int = param.get_int( l7vs::PARAM_COMP_SNMPAGENT, "port", err );
757         if( !err ){
758                 snmp_param.portno = tmp_int;
759         }
760         else{
761                 snmp_param.portno = PORT_DEFAULT;
762                 err.setter( false, "" );
763         }
764         // load interval from cf
765         tmp_int = param.get_int( l7vs::PARAM_COMP_SNMPAGENT, "interval", err );
766         if( !err ){
767                 snmp_param.interval = tmp_int;
768         }
769         else{
770                 snmp_param.interval = INTERVAL_DEFAULT;
771                 err.setter( false, "" );
772         }
773         tmp_int = param.get_int( l7vs::PARAM_COMP_SNMPAGENT, "status", err );
774         if( !err ){
775                 snmp_param.status = tmp_int;
776         }
777         else{
778                 snmp_param.status = 0;
779                 err.setter( false, "" );
780         }
781         load_loglevel();
782         return 0;
783 }
784
785 void l7vs::snmpbridge::load_loglevel(){
786         Logger logger( l7vs::LOG_CAT_L7VSD_SNMPBRIDGE, 16, "load_loglevel", __FILE__, __LINE__ );
787
788         //log level 取得
789         l7vs::Parameter param;
790         l7vs::error_code err;
791         std::string tmp_str;
792
793         snmp_param.loglevel.clear();
794
795         tmp_str = param.get_string( l7vs::PARAM_COMP_LOGGER, "snmpagent_start_stop", err );
796         if( !err ){
797                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_START_STOP, levelstring_map[tmp_str] ) );
798         }
799         else{
800                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_START_STOP, LOG_LV_INFO) );
801                 err.setter( false, "" );
802         }
803         tmp_str = param.get_string( l7vs::PARAM_COMP_LOGGER, "snmpagent_manager_receive", err );
804         if( !err ){
805                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_MANAGER_RECEIVE, levelstring_map[tmp_str] ) );
806         }
807         else{
808                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_MANAGER_RECEIVE, LOG_LV_INFO) );
809                 err.setter( false, "" );
810         }
811         tmp_str = param.get_string( l7vs::PARAM_COMP_LOGGER, "snmpagent_manager_send", err );
812         if( !err ){
813                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_MANAGER_SEND, levelstring_map[tmp_str] ) );
814         }
815         else{
816                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_MANAGER_SEND, LOG_LV_INFO) );
817                 err.setter( false, "" );
818         }
819         tmp_str = param.get_string( l7vs::PARAM_COMP_LOGGER, "snmpagent_l7vsd_receive", err );
820         if( !err ){
821                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_L7VSD_RECEIVE, levelstring_map[tmp_str] ) );
822         }
823         else{
824                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_L7VSD_RECEIVE, LOG_LV_INFO) );
825                 err.setter( false, "" );
826         }
827         tmp_str = param.get_string( l7vs::PARAM_COMP_LOGGER, "snmpagent_l7vsd_send", err );
828         if( !err ){
829                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_L7VSD_SEND, levelstring_map[tmp_str] ) );
830         }
831         else{
832                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_L7VSD_SEND, LOG_LV_INFO) );
833                 err.setter( false, "" );
834         }
835         tmp_str = param.get_string( l7vs::PARAM_COMP_LOGGER, "snmpagent_logger", err );
836         if( !err ){
837                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_LOGGER, levelstring_map[tmp_str] ) );
838         }
839         else{
840                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_LOGGER, LOG_LV_INFO) );
841                 err.setter( false, "" );
842         }
843         tmp_str = param.get_string( l7vs::PARAM_COMP_LOGGER, "snmpagent_parameter", err );
844         if( !err ){
845                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_PARAMETER, levelstring_map[tmp_str] ) );
846         }
847         else{
848                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_PARAMETER, LOG_LV_INFO) );
849                 err.setter( false, "" );
850         }
851         tmp_str = param.get_string( l7vs::PARAM_COMP_LOGGER, "snmpagent_system", err );
852         if( !err ){
853                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_SYSTEM, levelstring_map[tmp_str] ) );
854         }
855         else{
856                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_SYSTEM, LOG_LV_INFO) );
857                 err.setter( false, "" );
858         }
859         tmp_str = param.get_string( l7vs::PARAM_COMP_LOGGER, "snmpagent_system_memory", err );
860         if( !err ){
861                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_SYSTEM_MEMORY, levelstring_map[tmp_str] ) );
862         }
863         else{
864                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_SYSTEM_MEMORY, LOG_LV_INFO) );
865                 err.setter( false, "" );
866         }
867         tmp_str = param.get_string( l7vs::PARAM_COMP_LOGGER, "snmpagent_system_endpoint", err );
868         if( !err ){
869                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_SYSTEM_ENDPOINT, levelstring_map[tmp_str] ) );
870         }
871         else{
872                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_SYSTEM_ENDPOINT, LOG_LV_INFO) );
873                 err.setter( false, "" );
874         }
875         tmp_str = param.get_string( l7vs::PARAM_COMP_LOGGER, "snmpagent_system_signal", err );
876         if( !err ){
877                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_SYSTEM_SIGNAL, levelstring_map[tmp_str] ) );
878         }
879         else{
880                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_SYSTEM_SIGNAL, LOG_LV_INFO) );
881                 err.setter( false, "" );
882         }
883         tmp_str = param.get_string( l7vs::PARAM_COMP_LOGGER, "snmpagent_system_environment", err );
884         if( !err ){
885                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_SYSTEM_ENVIRONMENT, levelstring_map[tmp_str] ) );
886         }
887         else{
888                 snmp_param.loglevel.insert( std::pair<l7vs::LOG_CATEGORY_TAG,l7vs::LOG_LEVEL_TAG>( LOG_CAT_SNMPAGENT_SYSTEM_ENVIRONMENT, LOG_LV_INFO) );
889                 err.setter( false, "" );
890         }
891 }