blob: ca8522dd34d4f5dddaa096717edbdee84f8d673e [file] [log] [blame]
Adriana Kobylak5d6481f2015-10-29 21:44:55 -05001#include <stdio.h>
2#include <string.h>
3#include <stdint.h>
4
5#include "ipmid-api.h"
6#include "ipmid.H"
7#include "transporthandler.h"
8
9void register_netfn_transport_functions() __attribute__((constructor));
10
11ipmi_ret_t ipmi_transport_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
12 ipmi_request_t request, ipmi_response_t response,
13 ipmi_data_len_t data_len, ipmi_context_t context)
14{
15 printf("Handling TRANSPORT WILDCARD Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
16 // Status code.
17 ipmi_ret_t rc = IPMI_CC_OK;
18 *data_len = 0;
19 return rc;
20}
21
22struct set_lan_t {
23 uint8_t channel;
24 uint8_t parameter;
25 uint8_t data[8]; // Per IPMI spec, not expecting more than this size
26} __attribute__ ((packed));
27
28ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
29 ipmi_request_t request, ipmi_response_t response,
30 ipmi_data_len_t data_len, ipmi_context_t context)
31{
32 ipmi_ret_t rc = IPMI_CC_OK;
33 *data_len = 0;
34
35 int i = 0;
36 char syscmd[128];
37
38 printf("IPMI SET_LAN\n");
39
40 set_lan_t *reqptr = (set_lan_t*) request;
41
42 // TODO Use dbus interface once available. For now use cmd line.
43 // TODO Add the rest of the parameters like setting auth type
44 // TODO Add error handling
45
46 if (reqptr->parameter == 3) // IP
47 {
48 sprintf(syscmd, "ifconfig eth0 %d.%d.%d.%d", reqptr->data[0], reqptr->data[1], reqptr->data[2], reqptr->data[3]);
49 system(syscmd);
50 }
51 else if (reqptr->parameter == 6) // Subnet
52 {
53 sprintf(syscmd, "ifconfig eth0 netmask %d.%d.%d.%d", reqptr->data[0], reqptr->data[1], reqptr->data[2], reqptr->data[3]);
54 system(syscmd);
55 }
56 else if (reqptr->parameter == 12) // Gateway
57 {
58 sprintf(syscmd, "route add default gw %d.%d.%d.%d", reqptr->data[0], reqptr->data[1], reqptr->data[2], reqptr->data[3]);
59 system(syscmd);
60 }
61 else
62 {
63 fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
64 return IPMI_CC_PARM_NOT_SUPPORTED;
65 }
66
67 return rc;
68}
69
70struct get_lan_t {
71 uint8_t rev_channel;
72 uint8_t parameter;
73 uint8_t parameter_set;
74 uint8_t parameter_block;
75} __attribute__ ((packed));
76
77ipmi_ret_t ipmi_transport_get_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
78 ipmi_request_t request, ipmi_response_t response,
79 ipmi_data_len_t data_len, ipmi_context_t context)
80{
81 ipmi_ret_t rc = IPMI_CC_OK;
82 *data_len = 0;
83
84 const uint8_t current_revision = 0x11; // Current rev per IPMI Spec 2.0
85 char syscmd[128];
86 int i = 0;
87
88 printf("IPMI GET_LAN\n");
89
90 get_lan_t *reqptr = (get_lan_t*) request;
91
92 if (reqptr->rev_channel & 0x80) // Revision is bit 7
93 {
94 // Only current revision was requested
95 *data_len = sizeof(current_revision);
96 memcpy(response, &current_revision, *data_len);
97 return IPMI_CC_OK;
98 }
99
100 // TODO Use dbus interface once available. For now use ip cmd.
101 // TODO Add the rest of the parameters, like gateway
102
103 if (reqptr->parameter == 0) // In progress
104 {
105 uint8_t buf[] = {current_revision,0};
106 *data_len = sizeof(buf);
107 memcpy(response, &buf, *data_len);
108 return IPMI_CC_OK;
109 }
110 else if (reqptr->parameter == 1) // Authentication support
111 {
112 uint8_t buf[] = {current_revision,0x04};
113 *data_len = sizeof(buf);
114 memcpy(response, &buf, *data_len);
115 return IPMI_CC_OK;
116 }
117 else if (reqptr->parameter == 2) // Authentication enables
118 {
119 uint8_t buf[] = {current_revision,0x04,0x04,0x04,0x04,0x04};
120 *data_len = sizeof(buf);
121 memcpy(response, &buf, *data_len);
122 return IPMI_CC_OK;
123 }
124 else if (reqptr->parameter == 3) // IP
125 {
126 //string to parse: inet xx.xx.xxx.xxx/xx
127
128 uint8_t buf[5];
129 memcpy((void*)&buf[0], &current_revision, 1);
130
131 for (i=0; i<4; i++)
132 {
133 char ip[5];
134
135 sprintf(syscmd, "ip address show dev eth0|grep inet|cut -d'/' -f1|cut -d' ' -f 6|cut -d'.' -f%d|head -n1", i+1);
136 FILE *fp = popen(syscmd, "r");
137
138 memset(ip,0,sizeof(ip));
139 while (fgets(ip, sizeof(ip), fp) != 0)
140 {
141 int tmpip = strtoul(ip, NULL, 10);
142 memcpy((void*)&buf[i+1], &tmpip, 1);
143 }
144 pclose(fp);
145 }
146
147 *data_len = sizeof(buf);
148 memcpy(response, &buf, *data_len);
149 return IPMI_CC_OK;
150 }
151 else if (reqptr->parameter == 5) // MAC
152 {
153 //string to parse: link/ether xx:xx:xx:xx:xx:xx
154
155 uint8_t buf[7];
156 memcpy((void*)&buf[0], &current_revision, 1);
157
158 for (i=0; i<6; i++)
159 {
160 char mac[4];
161
162 sprintf(syscmd, "ip address show dev eth0|grep link|cut -d' ' -f 6|cut -d':' -f%d", i+1);
163 FILE *fp = popen(syscmd, "r");
164
165 memset(mac,0,sizeof(mac));
166 while (fgets(mac, sizeof(mac), fp) != 0)
167 {
168 int tmpmac = strtoul(mac, NULL, 16);
169 memcpy((void*)&buf[i+1], &tmpmac, 1);
170 }
171 pclose(fp);
172 }
173
174 *data_len = sizeof(buf);
175 memcpy(response, &buf, *data_len);
176 return IPMI_CC_OK;
177 }
178 else
179 {
180 fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
181 return IPMI_CC_PARM_NOT_SUPPORTED;
182 }
183
184 return rc;
185}
186
187void register_netfn_transport_functions()
188{
189 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_TRANSPORT, IPMI_CMD_WILDCARD);
190 ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_WILDCARD, NULL, ipmi_transport_wildcard);
191
192 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_TRANSPORT, IPMI_CMD_SET_LAN);
193 ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_SET_LAN, NULL, ipmi_transport_set_lan);
194
195 printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_TRANSPORT, IPMI_CMD_GET_LAN);
196 ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_GET_LAN, NULL, ipmi_transport_get_lan);
197
198 return;
199}
200