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