blob: 50bc4733e5eb18777a628c3851a36075201bc6a1 [file] [log] [blame]
Adriana Kobylak5d6481f2015-10-29 21:44:55 -05001#include <stdio.h>
2#include <string.h>
3#include <stdint.h>
Hariharasubramanian R83951912016-01-20 07:06:36 -06004#include <arpa/inet.h>
tomjose26e17732016-03-03 08:52:51 -06005#include <string>
Ratan Guptacc6cdbf2017-09-01 23:06:25 +05306#include <experimental/filesystem>
Adriana Kobylak5d6481f2015-10-29 21:44:55 -05007
Patrick Williams37af7332016-09-02 21:21:42 -05008#include "host-ipmid/ipmid-api.h"
Patrick Williams53a360e2016-08-12 22:01:02 -05009#include "ipmid.hpp"
Ratan Guptab8e99552017-07-27 07:07:48 +053010#include "transporthandler.hpp"
11#include "utils.hpp"
12
13#include <phosphor-logging/log.hpp>
14#include <phosphor-logging/elog-errors.hpp>
15#include "xyz/openbmc_project/Common/error.hpp"
Adriana Kobylak5d6481f2015-10-29 21:44:55 -050016
Hariharasubramanian R83951912016-01-20 07:06:36 -060017#define SYSTEMD_NETWORKD_DBUS 1
18
19#ifdef SYSTEMD_NETWORKD_DBUS
20#include <systemd/sd-bus.h>
Sergey Solomineb9b8142016-08-23 09:07:28 -050021#include <mapper.h>
Hariharasubramanian R83951912016-01-20 07:06:36 -060022#endif
23
Adriana Kobylake08fbc62016-02-09 16:17:23 -060024const int SIZE_MAC = 18; //xx:xx:xx:xx:xx:xx
Adriana Kobylake08fbc62016-02-09 16:17:23 -060025
Ratan Guptab8e99552017-07-27 07:07:48 +053026struct ChannelConfig_t channelConfig;
Hariharasubramanian R83951912016-01-20 07:06:36 -060027
Ratan Guptab8e99552017-07-27 07:07:48 +053028using namespace phosphor::logging;
29using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Ratan Guptacc6cdbf2017-09-01 23:06:25 +053030namespace fs = std::experimental::filesystem;
Hariharasubramanian R83951912016-01-20 07:06:36 -060031
Adriana Kobylak5d6481f2015-10-29 21:44:55 -050032void register_netfn_transport_functions() __attribute__((constructor));
33
Ratan Guptab8e99552017-07-27 07:07:48 +053034// Helper Function to get IP Address/NetMask/Gateway/MAC Address from Network Manager or
Nan Li3d0df912016-10-18 19:51:41 +080035// Cache based on Set-In-Progress State
Ratan Guptab8e99552017-07-27 07:07:48 +053036ipmi_ret_t getNetworkData(uint8_t lan_param, uint8_t* data)
tomjose26e17732016-03-03 08:52:51 -060037{
tomjose26e17732016-03-03 08:52:51 -060038 ipmi_ret_t rc = IPMI_CC_OK;
Ratan Guptab8e99552017-07-27 07:07:48 +053039 sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
Ratan Gupta533d03b2017-07-30 10:39:22 +053040
Ratan Guptab8e99552017-07-27 07:07:48 +053041 try
tomjose26e17732016-03-03 08:52:51 -060042 {
Ratan Guptab8e99552017-07-27 07:07:48 +053043 switch (lan_param)
tomjose26e17732016-03-03 08:52:51 -060044 {
Ratan Guptab8e99552017-07-27 07:07:48 +053045 case LAN_PARM_IP:
46 {
47 std::string ipaddress;
Patrick Venture585a1e92017-11-17 07:36:15 -080048 if (channelConfig.lan_set_in_progress == SET_COMPLETE)
Ratan Guptab8e99552017-07-27 07:07:48 +053049 {
Ratan Guptacc6cdbf2017-09-01 23:06:25 +053050 try
51 {
Ratan Guptadd646202017-11-21 17:46:59 +053052 auto ipObjectInfo = ipmi::getIPObject(
53 bus,
54 ipmi::network::IP_INTERFACE,
55 ipmi::network::ROOT,
56 ipmi::network::IP_TYPE);
57
58 auto properties = ipmi::getAllDbusProperties(
59 bus,
60 ipObjectInfo.second,
61 ipObjectInfo.first,
62 ipmi::network::IP_INTERFACE);
63
64 ipaddress = properties["Address"].get<std::string>();
Ratan Guptab8e99552017-07-27 07:07:48 +053065
Ratan Guptacc6cdbf2017-09-01 23:06:25 +053066 }
67 // ignore the exception, as it is a valid condtion that
68 // system is not confiured with any ip.
69 catch (InternalFailure& e)
70 {
71 // nothing to do.
72 }
Ratan Guptab8e99552017-07-27 07:07:48 +053073 }
Patrick Venture585a1e92017-11-17 07:36:15 -080074 else if (channelConfig.lan_set_in_progress == SET_IN_PROGRESS)
Ratan Guptab8e99552017-07-27 07:07:48 +053075 {
76 ipaddress = channelConfig.ipaddr;
77 }
78
79 inet_pton(AF_INET, ipaddress.c_str(),
80 reinterpret_cast<void*>(data));
81 }
82 break;
83
Ratan Guptacc6cdbf2017-09-01 23:06:25 +053084 case LAN_PARM_IPSRC:
Ratan Guptab8e99552017-07-27 07:07:48 +053085 {
Ratan Guptacc6cdbf2017-09-01 23:06:25 +053086 std::string networkInterfacePath;
87
Patrick Venture585a1e92017-11-17 07:36:15 -080088 if (channelConfig.lan_set_in_progress == SET_COMPLETE)
Ratan Guptab8e99552017-07-27 07:07:48 +053089 {
Ratan Guptacc6cdbf2017-09-01 23:06:25 +053090 try
91 {
92 ipmi::ObjectTree ancestorMap;
93 // if the system is having ip object,then
94 // get the IP object.
95 auto ipObject = ipmi::getDbusObject(
96 bus,
97 ipmi::network::IP_INTERFACE,
98 ipmi::network::ROOT,
99 ipmi::network::IP_TYPE);
Ratan Guptab8e99552017-07-27 07:07:48 +0530100
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530101 // Get the parent interface of the IP object.
102 try
103 {
104 ipmi::InterfaceList interfaces;
105 interfaces.emplace_back(
106 ipmi::network::ETHERNET_INTERFACE);
Ratan Guptab8e99552017-07-27 07:07:48 +0530107
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530108 ancestorMap = ipmi::getAllAncestors(
109 bus,
110 ipObject.first,
111 std::move(interfaces));
112 }
113 catch (InternalFailure& e)
114 {
115 // if unable to get the parent interface
116 // then commit the error and return.
117 log<level::ERR>("Unable to get the parent interface",
118 entry("PATH=%s", ipObject.first.c_str()),
119 entry("INTERFACE=%s",
120 ipmi::network::ETHERNET_INTERFACE));
121 break;
122
123 }
124 // for an ip object there would be single parent
125 // interface.
126 networkInterfacePath = ancestorMap.begin()->first;
127 }
128 catch (InternalFailure& e)
129 {
130 // if there is no ip configured on the system,then
131 // get the network interface object.
132 auto networkInterfaceObject = ipmi::getDbusObject(
133 bus,
134 ipmi::network::ETHERNET_INTERFACE,
135 ipmi::network::ROOT,
136 ipmi::network::INTERFACE);
137
138 networkInterfacePath = networkInterfaceObject.first;
139 }
140
141 auto variant = ipmi::getDbusProperty(
142 bus,
143 ipmi::network::SERVICE,
144 networkInterfacePath,
145 ipmi::network::ETHERNET_INTERFACE,
146 "DHCPEnabled");
147
148 auto dhcpEnabled = variant.get<bool>();
149 // As per IPMI spec 2=>DHCP, 1=STATIC
150 auto ipsrc = dhcpEnabled ? ipmi::network::IPOrigin::DHCP :
151 ipmi::network::IPOrigin::STATIC;
152
153 memcpy(data, &ipsrc, ipmi::network::IPSRC_SIZE_BYTE);
154 }
Patrick Venture585a1e92017-11-17 07:36:15 -0800155 else if (channelConfig.lan_set_in_progress == SET_IN_PROGRESS)
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530156 {
157 memcpy(data, &(channelConfig.ipsrc),
158 ipmi::network::IPSRC_SIZE_BYTE);
159 }
160 }
161 break;
162
163 case LAN_PARM_SUBNET:
164 {
165 unsigned long mask {};
Patrick Venture585a1e92017-11-17 07:36:15 -0800166 if (channelConfig.lan_set_in_progress == SET_COMPLETE)
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530167 {
168 try
169 {
Ratan Guptadd646202017-11-21 17:46:59 +0530170 auto ipObjectInfo = ipmi::getIPObject(
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530171 bus,
172 ipmi::network::IP_INTERFACE,
173 ipmi::network::ROOT,
174 ipmi::network::IP_TYPE);
175
176 auto properties = ipmi::getAllDbusProperties(
177 bus,
178 ipObjectInfo.second,
179 ipObjectInfo.first,
180 ipmi::network::IP_INTERFACE);
181
182 auto prefix = properties["PrefixLength"].get<uint8_t>();
183 mask = ipmi::network::MASK_32_BIT;
184 mask = htonl(mask << (ipmi::network::BITS_32 - prefix));
185 }
186 // ignore the exception, as it is a valid condtion that
187 // system is not confiured with any ip.
188 catch (InternalFailure& e)
189 {
190 // nothing to do
191 }
Ratan Guptab8e99552017-07-27 07:07:48 +0530192 memcpy(data, &mask, ipmi::network::IPV4_ADDRESS_SIZE_BYTE);
193 }
Patrick Venture585a1e92017-11-17 07:36:15 -0800194 else if (channelConfig.lan_set_in_progress == SET_IN_PROGRESS)
Ratan Guptab8e99552017-07-27 07:07:48 +0530195 {
196 inet_pton(AF_INET, channelConfig.netmask.c_str(),
197 reinterpret_cast<void*>(data));
Ratan Guptab8e99552017-07-27 07:07:48 +0530198 }
199
200 }
201 break;
202
203 case LAN_PARM_GATEWAY:
204 {
205 std::string gateway;
206
Patrick Venture585a1e92017-11-17 07:36:15 -0800207 if (channelConfig.lan_set_in_progress == SET_COMPLETE)
Ratan Guptab8e99552017-07-27 07:07:48 +0530208 {
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530209 try
210 {
211 auto systemObject = ipmi::getDbusObject(
212 bus,
213 ipmi::network::SYSTEMCONFIG_INTERFACE,
214 ipmi::network::ROOT);
Ratan Guptab8e99552017-07-27 07:07:48 +0530215
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530216 auto systemProperties = ipmi::getAllDbusProperties(
217 bus,
218 systemObject.second,
219 systemObject.first,
220 ipmi::network::SYSTEMCONFIG_INTERFACE);
Ratan Guptab8e99552017-07-27 07:07:48 +0530221
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530222 gateway = systemProperties["DefaultGateway"].get<
223 std::string>();
224 }
225 // ignore the exception, as it is a valid condtion that
226 // system is not confiured with any ip.
227 catch (InternalFailure& e)
228 {
229 // nothing to do
230 }
Ratan Guptab8e99552017-07-27 07:07:48 +0530231
232 }
Patrick Venture585a1e92017-11-17 07:36:15 -0800233 else if (channelConfig.lan_set_in_progress == SET_IN_PROGRESS)
Ratan Guptab8e99552017-07-27 07:07:48 +0530234 {
235 gateway = channelConfig.gateway;
236 }
237
238 inet_pton(AF_INET, gateway.c_str(),
239 reinterpret_cast<void*>(data));
Ratan Guptab8e99552017-07-27 07:07:48 +0530240 }
241 break;
242
243 case LAN_PARM_MAC:
244 {
245 std::string macAddress;
Patrick Venture585a1e92017-11-17 07:36:15 -0800246 if (channelConfig.lan_set_in_progress == SET_COMPLETE)
Ratan Guptab8e99552017-07-27 07:07:48 +0530247 {
248 auto macObjectInfo = ipmi::getDbusObject(
249 bus,
250 ipmi::network::MAC_INTERFACE,
251 ipmi::network::ROOT);
252
253 auto variant = ipmi::getDbusProperty(
254 bus,
255 macObjectInfo.second,
256 macObjectInfo.first,
257 ipmi::network::MAC_INTERFACE,
258 "MACAddress");
259
260 macAddress = variant.get<std::string>();
261
262 }
Patrick Venture585a1e92017-11-17 07:36:15 -0800263 else if (channelConfig.lan_set_in_progress == SET_IN_PROGRESS)
Ratan Guptab8e99552017-07-27 07:07:48 +0530264 {
265 macAddress = channelConfig.macAddress;
266 }
267
268 sscanf(macAddress.c_str(), ipmi::network::MAC_ADDRESS_FORMAT,
269 (data),
270 (data + 1),
271 (data + 2),
272 (data + 3),
273 (data + 4),
274 (data + 5));
275 }
276 break;
277
Ratan Gupta533d03b2017-07-30 10:39:22 +0530278 case LAN_PARM_VLAN:
279 {
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530280 uint16_t vlanID {};
Patrick Venture585a1e92017-11-17 07:36:15 -0800281 if (channelConfig.lan_set_in_progress == SET_COMPLETE)
Ratan Gupta533d03b2017-07-30 10:39:22 +0530282 {
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530283 try
Ratan Gupta533d03b2017-07-30 10:39:22 +0530284 {
Ratan Guptadd646202017-11-21 17:46:59 +0530285 auto ipObjectInfo = ipmi::getIPObject(
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530286 bus,
287 ipmi::network::IP_INTERFACE,
288 ipmi::network::ROOT,
289 ipmi::network::IP_TYPE);
290
291 vlanID = static_cast<uint16_t>(
292 ipmi::network::getVLAN(ipObjectInfo.first));
293
294 vlanID = htole16(vlanID);
295
296 if (vlanID)
297 {
298 //Enable the 16th bit
299 vlanID |= htole16(ipmi::network::VLAN_ENABLE_MASK);
300 }
301 }
302 // ignore the exception, as it is a valid condtion that
303 // system is not confiured with any ip.
304 catch (InternalFailure& e)
305 {
306 // nothing to do
Ratan Gupta533d03b2017-07-30 10:39:22 +0530307 }
308
309 memcpy(data, &vlanID, ipmi::network::VLAN_SIZE_BYTE);
310 }
Patrick Venture585a1e92017-11-17 07:36:15 -0800311 else if (channelConfig.lan_set_in_progress == SET_IN_PROGRESS)
Ratan Gupta533d03b2017-07-30 10:39:22 +0530312 {
313 memcpy(data, &(channelConfig.vlanID),
314 ipmi::network::VLAN_SIZE_BYTE);
315 }
316 }
317 break;
318
Ratan Guptab8e99552017-07-27 07:07:48 +0530319 default:
320 rc = IPMI_CC_PARM_OUT_OF_RANGE;
tomjose26e17732016-03-03 08:52:51 -0600321 }
322 }
Ratan Guptab8e99552017-07-27 07:07:48 +0530323 catch (InternalFailure& e)
tomjose26e17732016-03-03 08:52:51 -0600324 {
Ratan Guptab8e99552017-07-27 07:07:48 +0530325 commit<InternalFailure>();
326 rc = IPMI_CC_UNSPECIFIED_ERROR;
327 return rc;
tomjose26e17732016-03-03 08:52:51 -0600328 }
tomjose26e17732016-03-03 08:52:51 -0600329 return rc;
330}
331
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500332ipmi_ret_t ipmi_transport_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
333 ipmi_request_t request, ipmi_response_t response,
334 ipmi_data_len_t data_len, ipmi_context_t context)
335{
336 printf("Handling TRANSPORT WILDCARD Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
337 // Status code.
Nan Li70aa8d92016-08-29 00:11:10 +0800338 ipmi_ret_t rc = IPMI_CC_INVALID;
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500339 *data_len = 0;
340 return rc;
341}
342
Ratan Guptab8e99552017-07-27 07:07:48 +0530343struct set_lan_t
344{
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500345 uint8_t channel;
346 uint8_t parameter;
347 uint8_t data[8]; // Per IPMI spec, not expecting more than this size
Ratan Guptab8e99552017-07-27 07:07:48 +0530348} __attribute__((packed));
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500349
Ratan Guptab8e99552017-07-27 07:07:48 +0530350ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn,
351 ipmi_cmd_t cmd,
352 ipmi_request_t request,
353 ipmi_response_t response,
354 ipmi_data_len_t data_len,
355 ipmi_context_t context)
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500356{
357 ipmi_ret_t rc = IPMI_CC_OK;
358 *data_len = 0;
Nan Li3d0df912016-10-18 19:51:41 +0800359
Ratan Guptab8e99552017-07-27 07:07:48 +0530360 char ipaddr[INET_ADDRSTRLEN];
361 char netmask[INET_ADDRSTRLEN];
362 char gateway[INET_ADDRSTRLEN];
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500363
Ratan Guptab8e99552017-07-27 07:07:48 +0530364 auto reqptr = reinterpret_cast<const set_lan_t*>(request);
365 sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500366
Ratan Guptab8e99552017-07-27 07:07:48 +0530367 switch (reqptr->parameter)
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500368 {
Ratan Guptab8e99552017-07-27 07:07:48 +0530369 case LAN_PARM_IP:
Hariharasubramanian R83951912016-01-20 07:06:36 -0600370 {
Ratan Guptab8e99552017-07-27 07:07:48 +0530371 snprintf(ipaddr, INET_ADDRSTRLEN, ipmi::network::IP_ADDRESS_FORMAT,
372 reqptr->data[0], reqptr->data[1],
373 reqptr->data[2], reqptr->data[3]);
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500374
Ratan Guptab8e99552017-07-27 07:07:48 +0530375 channelConfig.ipaddr.assign(ipaddr);
376
377 }
378 break;
379
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530380 case LAN_PARM_IPSRC:
381 {
382 uint8_t ipsrc{};
383 memcpy(&ipsrc, reqptr->data, ipmi::network::IPSRC_SIZE_BYTE);
384 channelConfig.ipsrc = static_cast<ipmi::network::IPOrigin>(ipsrc);
385 }
386 break;
387
Ratan Guptab8e99552017-07-27 07:07:48 +0530388 case LAN_PARM_MAC:
389 {
390 char mac[SIZE_MAC];
391
392 snprintf(mac, SIZE_MAC, ipmi::network::MAC_ADDRESS_FORMAT,
393 reqptr->data[0],
394 reqptr->data[1],
395 reqptr->data[2],
396 reqptr->data[3],
397 reqptr->data[4],
398 reqptr->data[5]);
399
400 auto macObjectInfo = ipmi::getDbusObject(
401 bus,
402 ipmi::network::MAC_INTERFACE,
403 ipmi::network::ROOT,
404 ipmi::network::INTERFACE);
405
406 ipmi::setDbusProperty(bus,
407 macObjectInfo.second,
408 macObjectInfo.first,
409 ipmi::network::MAC_INTERFACE,
410 "MACAddress",
411 std::string(mac));
412
413 channelConfig.macAddress = mac;
414
415 }
416 break;
417
418 case LAN_PARM_SUBNET:
419 {
420 snprintf(netmask, INET_ADDRSTRLEN, ipmi::network::IP_ADDRESS_FORMAT,
421 reqptr->data[0], reqptr->data[1],
422 reqptr->data[2], reqptr->data[3]);
423 channelConfig.netmask.assign(netmask);
424 }
425 break;
426
427 case LAN_PARM_GATEWAY:
428 {
429 snprintf(gateway, INET_ADDRSTRLEN, ipmi::network::IP_ADDRESS_FORMAT,
430 reqptr->data[0], reqptr->data[1],
431 reqptr->data[2], reqptr->data[3]);
432 channelConfig.gateway.assign(gateway);
433
434 }
435 break;
436
Ratan Gupta533d03b2017-07-30 10:39:22 +0530437 case LAN_PARM_VLAN:
438 {
439 uint16_t vlan {};
440 memcpy(&vlan, reqptr->data, ipmi::network::VLAN_SIZE_BYTE);
441 // We are not storing the enable bit
442 // We assume that ipmitool always send enable
443 // bit as 1.
444 vlan = le16toh(vlan);
445 channelConfig.vlanID = vlan;
446 }
447 break;
448
Ratan Guptab8e99552017-07-27 07:07:48 +0530449 case LAN_PARM_INPROGRESS:
450 {
451 if (reqptr->data[0] == SET_COMPLETE)
452 {
Patrick Venture585a1e92017-11-17 07:36:15 -0800453 channelConfig.lan_set_in_progress = SET_COMPLETE;
Ratan Guptab8e99552017-07-27 07:07:48 +0530454
455 log<level::INFO>("Network data from Cache",
456 entry("PREFIX=%s", channelConfig.netmask.c_str()),
457 entry("ADDRESS=%s", channelConfig.ipaddr.c_str()),
Ratan Gupta533d03b2017-07-30 10:39:22 +0530458 entry("GATEWAY=%s", channelConfig.gateway.c_str()),
459 entry("VLAN=%d", channelConfig.vlanID));
Ratan Guptab8e99552017-07-27 07:07:48 +0530460
461 log<level::INFO>("Use Set Channel Access command to apply");
462
463 }
464 else if (reqptr->data[0] == SET_IN_PROGRESS) // Set In Progress
465 {
Patrick Venture585a1e92017-11-17 07:36:15 -0800466 channelConfig.lan_set_in_progress = SET_IN_PROGRESS;
Ratan Guptab8e99552017-07-27 07:07:48 +0530467 }
468
469 }
470 break;
471
472 default:
473 {
Ratan Guptab8e99552017-07-27 07:07:48 +0530474 rc = IPMI_CC_PARM_NOT_SUPPORTED;
475 }
476
477 }
vishwa1eaea4f2016-02-26 11:57:40 -0600478
tomjose26e17732016-03-03 08:52:51 -0600479 return rc;
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500480}
481
Ratan Guptab8e99552017-07-27 07:07:48 +0530482struct get_lan_t
483{
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500484 uint8_t rev_channel;
485 uint8_t parameter;
486 uint8_t parameter_set;
487 uint8_t parameter_block;
Ratan Guptab8e99552017-07-27 07:07:48 +0530488} __attribute__((packed));
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500489
Ratan Guptab8e99552017-07-27 07:07:48 +0530490ipmi_ret_t ipmi_transport_get_lan(ipmi_netfn_t netfn,
491 ipmi_cmd_t cmd,
492 ipmi_request_t request,
493 ipmi_response_t response,
494 ipmi_data_len_t data_len,
495 ipmi_context_t context)
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500496{
497 ipmi_ret_t rc = IPMI_CC_OK;
498 *data_len = 0;
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500499 const uint8_t current_revision = 0x11; // Current rev per IPMI Spec 2.0
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500500
501 get_lan_t *reqptr = (get_lan_t*) request;
502
503 if (reqptr->rev_channel & 0x80) // Revision is bit 7
504 {
505 // Only current revision was requested
506 *data_len = sizeof(current_revision);
507 memcpy(response, &current_revision, *data_len);
508 return IPMI_CC_OK;
509 }
510
Adriana Kobylake08fbc62016-02-09 16:17:23 -0600511 if (reqptr->parameter == LAN_PARM_INPROGRESS)
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500512 {
Patrick Venture585a1e92017-11-17 07:36:15 -0800513 uint8_t buf[] = {current_revision, channelConfig.lan_set_in_progress};
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500514 *data_len = sizeof(buf);
515 memcpy(response, &buf, *data_len);
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500516 }
Adriana Kobylake08fbc62016-02-09 16:17:23 -0600517 else if (reqptr->parameter == LAN_PARM_AUTHSUPPORT)
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500518 {
519 uint8_t buf[] = {current_revision,0x04};
520 *data_len = sizeof(buf);
521 memcpy(response, &buf, *data_len);
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500522 }
Adriana Kobylake08fbc62016-02-09 16:17:23 -0600523 else if (reqptr->parameter == LAN_PARM_AUTHENABLES)
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500524 {
525 uint8_t buf[] = {current_revision,0x04,0x04,0x04,0x04,0x04};
526 *data_len = sizeof(buf);
527 memcpy(response, &buf, *data_len);
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500528 }
Ratan Guptab8e99552017-07-27 07:07:48 +0530529 else if ((reqptr->parameter == LAN_PARM_IP) ||
530 (reqptr->parameter == LAN_PARM_SUBNET) ||
531 (reqptr->parameter == LAN_PARM_GATEWAY) ||
532 (reqptr->parameter == LAN_PARM_MAC))
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500533 {
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530534 uint8_t buf[ipmi::network::MAC_ADDRESS_SIZE_BYTE + 1] = {};
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500535
tomjose26e17732016-03-03 08:52:51 -0600536 *data_len = sizeof(current_revision);
537 memcpy(buf, &current_revision, *data_len);
538
Ratan Guptab8e99552017-07-27 07:07:48 +0530539 if (getNetworkData(reqptr->parameter, &buf[1]) == IPMI_CC_OK)
vishwa1eaea4f2016-02-26 11:57:40 -0600540 {
Ratan Guptab8e99552017-07-27 07:07:48 +0530541 if (reqptr->parameter == LAN_PARM_MAC)
542 {
543 *data_len = sizeof(buf);
544 }
545 else
546 {
547 *data_len = ipmi::network::IPV4_ADDRESS_SIZE_BYTE + 1;
548 }
tomjose26e17732016-03-03 08:52:51 -0600549 memcpy(response, &buf, *data_len);
Adriana Kobylak342df102016-02-10 13:48:16 -0600550 }
tomjose26e17732016-03-03 08:52:51 -0600551 else
Hariharasubramanian R83951912016-01-20 07:06:36 -0600552 {
tomjose26e17732016-03-03 08:52:51 -0600553 rc = IPMI_CC_UNSPECIFIED_ERROR;
Hariharasubramanian R83951912016-01-20 07:06:36 -0600554 }
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500555 }
Ratan Gupta533d03b2017-07-30 10:39:22 +0530556 else if (reqptr->parameter == LAN_PARM_VLAN)
557 {
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530558 uint8_t buf[ipmi::network::VLAN_SIZE_BYTE + 1] = {};
Ratan Gupta533d03b2017-07-30 10:39:22 +0530559
560 *data_len = sizeof(current_revision);
561 memcpy(buf, &current_revision, *data_len);
562 if (getNetworkData(reqptr->parameter, &buf[1]) == IPMI_CC_OK)
563 {
564 *data_len = sizeof(buf);
565 memcpy(response, &buf, *data_len);
566 }
567 }
Ratan Guptacc6cdbf2017-09-01 23:06:25 +0530568 else if (reqptr->parameter == LAN_PARM_IPSRC)
569 {
570 uint8_t buff[ipmi::network::IPSRC_SIZE_BYTE + 1] = {};
571 *data_len = sizeof(current_revision);
572 memcpy(buff, &current_revision, *data_len);
573 if (getNetworkData(reqptr->parameter, &buff[1]) == IPMI_CC_OK)
574 {
575 *data_len = sizeof(buff);
576 memcpy(response, &buff, *data_len);
577 }
578 }
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500579 else
580 {
Ratan Guptab8e99552017-07-27 07:07:48 +0530581 log<level::ERR>("Unsupported parameter",
582 entry("PARAMETER=0x%x", reqptr->parameter));
vishwa1eaea4f2016-02-26 11:57:40 -0600583 rc = IPMI_CC_PARM_NOT_SUPPORTED;
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500584 }
585
586 return rc;
587}
588
589void register_netfn_transport_functions()
590{
Tom05732372016-09-06 17:21:23 +0530591 // <Wildcard Command>
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500592 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_TRANSPORT, IPMI_CMD_WILDCARD);
Tom05732372016-09-06 17:21:23 +0530593 ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_WILDCARD, NULL, ipmi_transport_wildcard,
594 PRIVILEGE_USER);
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500595
Tom05732372016-09-06 17:21:23 +0530596 // <Set LAN Configuration Parameters>
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500597 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_TRANSPORT, IPMI_CMD_SET_LAN);
Tom05732372016-09-06 17:21:23 +0530598 ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_SET_LAN, NULL, ipmi_transport_set_lan,
599 PRIVILEGE_ADMIN);
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500600
Tom05732372016-09-06 17:21:23 +0530601 // <Get LAN Configuration Parameters>
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500602 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_TRANSPORT, IPMI_CMD_GET_LAN);
Tom05732372016-09-06 17:21:23 +0530603 ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_GET_LAN, NULL, ipmi_transport_get_lan,
604 PRIVILEGE_OPERATOR);
Adriana Kobylak5d6481f2015-10-29 21:44:55 -0500605
606 return;
607}