1 /*****************************************************************************
3 * main function to process ipv4 packets
6 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ****************************************************************************/
21 #include <dhcp/pkt4.h>
22 #include <log/logger.h>
23 #include <log/macros.h>
24 #include <log/message_initializer.h>
25 #include "library_common.h"
26 #include <curl/curl.h>
29 using namespace isc::dhcp;
30 using namespace isc::hooks;
32 using namespace isc::log;
33 namespace pt = boost::property_tree;
36 isc::log::Logger logger("sdnc-notify-logger");
37 const char* log_messages[] = {
38 "SNL_BASE", "message: %1",
39 "SNL_PKT_SEND", "Outgoing packet: \n%1",
40 "SNL_CURL_RECEIVED", "Received: \n%1",
41 "SNL_CURL_FAILED", "Unable to receive data from %1",
45 /// Initializer for log messages.
46 const MessageInitializer message_initializer(log_messages);
49 int pkt4_send(CalloutHandle& handle) {
54 struct curl_slist *list=NULL;
55 bool perform_updates = 0;
61 FILE *response_memfile;
72 Pkt4Ptr response4_ptr;
75 // Boost / json related variables.
78 boost::optional<std::string> siaddr_json_field;
81 handle.getArgument("response4", response4_ptr);
82 hwaddr_ptr = response4_ptr->getHWAddr();
83 isc::asiolink::IOAddress new_yiaddr(response4_ptr->getYiaddr());
84 hwaddr = hwaddr_ptr->toText(false);
85 yiaddr = new_yiaddr.toText();
86 msg_name = response4_ptr->getName();
87 post_data = "{ macaddr=" + hwaddr + "&yiaddr=" + yiaddr + "&msg=" + msg_name + "}";
88 final_url = json_params[0] + hwaddr;
89 LOG_DEBUG(logger, 0, "SNL_BASE").arg(final_url);
90 LOG_DEBUG(logger, 0, "SNL_BASE").arg(yiaddr);
93 if ( msg_name == "DHCPACK")
96 if (!perform_updates) {
97 LOG_WARN(logger, "SNL_BASE").arg("Nothing to update.");
101 curl_global_init(CURL_GLOBAL_DEFAULT);
102 curl = curl_easy_init();
104 curl_global_cleanup();
105 LOG_ERROR(logger, "SNL_BASE").arg("Could not initialize curl");
109 list = curl_slist_append(list, "Accept: application/json");
111 curl_easy_cleanup(curl);
112 curl_global_cleanup();
113 LOG_ERROR(logger, "SNL_BASE").arg("Could not create curl slist.");
117 response_memfile = open_memstream (&bp, &size);
118 if (response_memfile == NULL) {
119 curl_easy_cleanup(curl);
120 curl_global_cleanup();
121 LOG_ERROR(logger, "SNL_BASE").arg("Could not create memfile.");
126 curl_opt_res += curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
127 curl_opt_res += curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
129 // If we don't set a timeout, curl will try for 300 seconds by default.
130 curl_opt_res += curl_easy_setopt(curl, CURLOPT_TIMEOUT, 1L);
131 curl_opt_res += curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 1L);
132 // libcurl's docs say to cast as void, don't blame me.
133 curl_opt_res += curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)response_memfile);
134 // CURLOPT_URL takes a char*
135 curl_opt_res += curl_easy_setopt(curl, CURLOPT_URL, (final_url).c_str());
137 // let curl use strlen
138 curl_opt_res += curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, -1L );
139 curl_opt_res += curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data.c_str() );
140 curl_opt_res += curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
142 #ifdef SKIP_PEER_VERIFICATION
143 curl_opt_res += curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
146 #ifdef SKIP_HOSTNAME_VERIFICATION
147 curl_opt_res += curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
149 if (curl_opt_res > 0) {
150 fclose(response_memfile);
152 curl_easy_cleanup(curl);
153 curl_global_cleanup();
154 LOG_ERROR(logger, "SNL_BASE").arg("Error setting curl options.");
157 res = curl_easy_perform(curl);
158 /* Check for errors */
159 if(res != CURLE_OK) {
160 fclose(response_memfile);
162 curl_easy_cleanup(curl);
163 curl_global_cleanup();
164 LOG_ERROR(logger, "SNL_CURL_FAILED").arg(ss.str());
167 // make bp available for reading.
168 fclose(response_memfile);
169 curl_easy_cleanup(curl);
170 curl_global_cleanup();
173 LOG_DEBUG(logger, 0, "SNL_CURL_RECEIVED").arg(ss.str());
174 // Load the json file in this ptree
177 LOG_DEBUG(logger, 0, "SNL_PKT_SEND").arg(response4_ptr->toText());