Skip to content

Commit 2990a05

Browse files
committed
enable mctp-req to send any mctp commands
Signed-off-by: Peng85282 <peng.wang@penguinsolutions.com>
1 parent ef0d2dc commit 2990a05

File tree

1 file changed

+94
-38
lines changed

1 file changed

+94
-38
lines changed

src/mctp-req.c

Lines changed: 94 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <string.h>
1515
#include <err.h>
1616
#include <sys/socket.h>
17+
#include <poll.h>
1718

1819
#include "mctp.h"
1920
#include "mctp-util.h"
@@ -28,10 +29,11 @@ static const uint8_t MCTP_TYPE_VENDOR_PCIE = 0x7e;
2829

2930
/* lladdrlen != -1 to ignore ifindex/lladdr */
3031
static int mctp_req(unsigned int net, mctp_eid_t eid, unsigned int ifindex,
31-
uint8_t *lladdr, int lladdrlen, uint8_t *data, size_t len)
32+
uint8_t *lladdr, int lladdrlen, uint8_t *data, size_t len,
33+
int8_t type, unsigned int timeout)
3234
{
3335
struct sockaddr_mctp_ext addr;
34-
unsigned char *payload, *buf;
36+
unsigned char *buf;
3537
socklen_t addrlen;
3638
int rc, sd, val;
3739
size_t i, buf_len;
@@ -45,24 +47,10 @@ static int mctp_req(unsigned int net, mctp_eid_t eid, unsigned int ifindex,
4547
addr.smctp_base.smctp_family = AF_MCTP;
4648
addr.smctp_base.smctp_network = net;
4749
addr.smctp_base.smctp_addr.s_addr = eid;
48-
addr.smctp_base.smctp_type = MCTP_TYPE_VENDOR_PCIE;
50+
addr.smctp_base.smctp_type = type;
4951
addr.smctp_base.smctp_tag = MCTP_TAG_OWNER;
50-
printf("req: sending to (net %d, eid %d), type 0x%x\n", net, eid,
51-
addr.smctp_base.smctp_type);
52-
53-
buf_len = len + sizeof(VENDOR_TYPE_ECHO);
54-
buf = malloc(buf_len);
55-
if (!buf)
56-
err(EXIT_FAILURE, "malloc");
57-
memcpy(buf, VENDOR_TYPE_ECHO, sizeof(VENDOR_TYPE_ECHO));
58-
payload = &buf[sizeof(VENDOR_TYPE_ECHO)];
59-
60-
if (data) {
61-
memcpy(payload, data, len);
62-
} else {
63-
for (i = 0; i < len; i++)
64-
payload[i] = i & 0xff;
65-
}
52+
printf("req: sending to (net %d, eid %d), type 0x%02x, len %zu\n", net,
53+
eid, type, len);
6654

6755
/* extended addressing */
6856
if (lladdrlen != -1) {
@@ -82,9 +70,23 @@ static int mctp_req(unsigned int net, mctp_eid_t eid, unsigned int ifindex,
8270
}
8371

8472
/* send data */
85-
rc = sendto(sd, buf, buf_len, 0, (struct sockaddr *)&addr, addrlen);
86-
if (rc != (int)buf_len)
87-
err(EXIT_FAILURE, "sendto(%zd)", buf_len);
73+
rc = sendto(sd, data, len, 0, (struct sockaddr *)&addr, addrlen);
74+
if (rc != (int)len)
75+
err(EXIT_FAILURE, "sendto(%zd)", len);
76+
77+
struct pollfd pfd = { .fd = sd, .events = POLLIN };
78+
if (poll(&pfd, 1, timeout) <= 0) {
79+
return -1;
80+
}
81+
82+
rc = recvfrom(sd, NULL, 0, MSG_PEEK | MSG_TRUNC, NULL, 0);
83+
if (rc < 0)
84+
err(EXIT_FAILURE, "recvfrom");
85+
buf_len = (size_t)rc;
86+
87+
buf = malloc(buf_len);
88+
if (!buf)
89+
err(EXIT_FAILURE, "malloc");
8890

8991
/* receive response */
9092
addrlen = sizeof(addr);
@@ -103,26 +105,46 @@ static int mctp_req(unsigned int net, mctp_eid_t eid, unsigned int ifindex,
103105
sizeof(struct sockaddr_mctp_ext),
104106
sizeof(struct sockaddr_mctp));
105107

106-
printf("req: message from (net %d, eid %d) type 0x%x len %zd\n",
108+
printf("rsp: message from (net %d, eid %d) type 0x%02x len %zd\n",
107109
addr.smctp_base.smctp_network, addr.smctp_base.smctp_addr.s_addr,
108-
addr.smctp_base.smctp_type, len);
110+
addr.smctp_base.smctp_type, buf_len);
109111
if (addrlen == sizeof(struct sockaddr_mctp_ext)) {
110112
printf(" ext ifindex %d ha[0]=0x%02x len %hhu\n",
111113
addr.smctp_ifindex, addr.smctp_haddr[0],
112114
addr.smctp_halen);
113115
}
114116

115-
if (memcmp(buf, VENDOR_TYPE_ECHO, sizeof(VENDOR_TYPE_ECHO)) != 0) {
116-
errx(EXIT_FAILURE, "unexpected vendor ID");
117+
printf("data:");
118+
for (i = 0; i < buf_len; i++) {
119+
if (i % 16 == 0)
120+
printf("\n%04X\t", i);
121+
printf("0x%02x ", buf[i]);
117122
}
123+
printf("\n");
124+
125+
if (type == MCTP_TYPE_VENDOR_PCIE &&
126+
!memcmp(data, VENDOR_TYPE_ECHO, sizeof(VENDOR_TYPE_ECHO))) {
127+
if (buf_len >= sizeof(VENDOR_TYPE_ECHO) &&
128+
memcmp(buf, VENDOR_TYPE_ECHO, sizeof(VENDOR_TYPE_ECHO))) {
129+
errx(EXIT_FAILURE, "unexpected vendor ID");
130+
}
118131

119-
for (i = 0; i < len; i++) {
120-
uint8_t exp = data ? data[i] : i & 0xff;
121-
if (payload[i] != exp)
132+
if (len != buf_len) {
122133
errx(EXIT_FAILURE,
123-
"payload mismatch at byte 0x%zx; "
124-
"sent 0x%02x, received 0x%02x",
125-
i, exp, buf[i]);
134+
"unmatched payload length, "
135+
"sent %zd bytes, but received %zd bytes",
136+
len - sizeof(VENDOR_TYPE_ECHO),
137+
buf_len - sizeof(VENDOR_TYPE_ECHO));
138+
}
139+
140+
for (i = sizeof(VENDOR_TYPE_ECHO); i < len; i++) {
141+
if (buf[i] != data[i])
142+
errx(EXIT_FAILURE,
143+
"payload mismatch at byte 0x%zx; "
144+
"sent 0x%02x, but received 0x%02x",
145+
i - sizeof(VENDOR_TYPE_ECHO), data[i],
146+
buf[i]);
147+
}
126148
}
127149

128150
return 0;
@@ -131,21 +153,29 @@ static int mctp_req(unsigned int net, mctp_eid_t eid, unsigned int ifindex,
131153
static void usage(void)
132154
{
133155
fprintf(stderr,
134-
"mctp-req [eid <eid>] [net <net>] [ifindex <ifindex> lladdr <hwaddr>] [len <len>]\n");
156+
"mctp-req [eid <eid>] [net <net>] [ifindex <ifindex> lladdr <hwaddr>]"
157+
" [timeout <ms>] [type <type>] [len <len>] [data <data>]\n");
135158
fprintf(stderr, "default eid %d net %d len %zd\n", DEFAULT_EID,
136159
DEFAULT_NET, DEFAULT_LEN);
160+
fprintf(stderr,
161+
"default to send <data> as payload of code construct echo command if"
162+
" type is not specified");
163+
fprintf(stderr, "<data> is colon separated hex bytes, e.g. cc:de:f0");
137164
}
138165

139166
int main(int argc, char **argv)
140167
{
141-
uint8_t *data, lladdr[MAX_ADDR_LEN];
168+
uint8_t *data = NULL, *buf, lladdr[MAX_ADDR_LEN];
142169
int lladdrlen = -1, datalen = -1;
143170
unsigned int net = DEFAULT_NET;
144171
mctp_eid_t eid = DEFAULT_EID;
145172
size_t len = DEFAULT_LEN, sz;
146173
char *endp, *optname, *optval;
147174
unsigned int tmp, ifindex;
175+
uint8_t type = MCTP_TYPE_VENDOR_PCIE;
176+
unsigned int timeout = 1000;
148177
bool valid_parse;
178+
bool echo_req = true;
149179
int i;
150180

151181
if (!(argc % 2)) {
@@ -174,16 +204,25 @@ int main(int argc, char **argv)
174204
net = tmp;
175205
} else if (!strcmp(optname, "ifindex")) {
176206
ifindex = tmp;
207+
} else if (!strcmp(optname, "timeout")) {
208+
timeout = tmp;
177209
} else if (!strcmp(optname, "len")) {
178210
if (tmp > 64 * 1024)
179211
errx(EXIT_FAILURE, "Bad len");
180212
len = tmp;
213+
} else if (!strcmp(optname, "type")) {
214+
if (tmp > 0xff)
215+
errx(EXIT_FAILURE, "Bad type");
216+
type = tmp;
217+
echo_req = false;
181218
} else if (!strcmp(optname, "data")) {
182219
sz = (strlen(optval) + 2) / 3;
183-
data = malloc(sz);
220+
data = malloc(sz + sizeof(VENDOR_TYPE_ECHO));
184221
if (!data)
185222
err(EXIT_FAILURE, "malloc");
186-
if (parse_hex_addr(optval, data, &sz)) {
223+
if (parse_hex_addr(optval,
224+
data + sizeof(VENDOR_TYPE_ECHO),
225+
&sz)) {
187226
errx(EXIT_FAILURE, "Bad data");
188227
}
189228
datalen = sz;
@@ -205,8 +244,25 @@ int main(int argc, char **argv)
205244
}
206245
}
207246

208-
if (data)
247+
if (data) {
209248
len = datalen;
249+
} else {
250+
data = malloc(len + sizeof(VENDOR_TYPE_ECHO));
251+
if (!data)
252+
err(EXIT_FAILURE, "malloc");
253+
buf = data + sizeof(VENDOR_TYPE_ECHO);
254+
for (i = 0; i < len; i++)
255+
*buf = i & 0xff;
256+
}
257+
258+
if (echo_req) {
259+
memcpy(data, VENDOR_TYPE_ECHO, sizeof(VENDOR_TYPE_ECHO));
260+
buf = data;
261+
len += sizeof(VENDOR_TYPE_ECHO);
262+
} else {
263+
buf = data + sizeof(VENDOR_TYPE_ECHO);
264+
}
210265

211-
return mctp_req(net, eid, ifindex, lladdr, lladdrlen, data, len);
266+
return mctp_req(net, eid, ifindex, lladdr, lladdrlen, buf, len, type,
267+
timeout);
212268
}

0 commit comments

Comments
 (0)