2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
13 * Copyright (c) 2018, Joyent, Inc.
17 * Receive a raw Ethernet frame from dlsend.
40 static uint_t dlrecv_sap
= DLSEND_SAP
;
41 static const char *dlrecv_prog
;
44 dlrecv_usage(const char *fmt
, ...)
49 (void) fprintf(stderr
, "%s: ", dlrecv_prog
);
51 (void) vfprintf(stderr
, fmt
, ap
);
55 (void) fprintf(stderr
, "Usage: %s [-s sap] device\n"
56 "\t-s sap\tspecify SAP to send on\n",
61 dlrecv_isvalid(dlsend_msg_t
*msg
)
67 for (i
= 0; i
< sizeof (msg
->dm_host
); i
++) {
68 if (!isprint(msg
->dm_host
[i
]) &&
69 msg
->dm_host
[i
] != '\0') {
70 warnx("Encountered bad byte in dm_host[%d]\n",
75 if (msg
->dm_host
[i
] == '\0')
80 warnx("Missing NUL in dm_host\n");
85 for (i
= 0; i
< sizeof (msg
->dm_mesg
); i
++) {
86 if (!isprint(msg
->dm_mesg
[i
]) &&
87 msg
->dm_mesg
[i
] != '\0') {
88 warnx("Encountered bad byte in dm_mesg[%d]\n",
93 if (msg
->dm_mesg
[i
] == '\0')
98 warnx("Missing NUL in dm_mesg\n");
102 if (strcmp(msg
->dm_mesg
, DLSEND_MSG
) != 0) {
103 warnx("Missing expected message (%s)\n", DLSEND_MSG
);
111 dlrecv_print(dlsend_msg_t
*msg
, dlpi_recvinfo_t
*rinfo
, boolean_t invalid
)
115 (void) printf("Received %s from ", invalid
?
116 "invalid message" : "Elbereth");
118 for (i
= 0; i
< rinfo
->dri_destaddrlen
; i
++) {
119 (void) printf("%02x", rinfo
->dri_destaddr
[i
]);
120 if (i
+ 1 != rinfo
->dri_destaddrlen
)
128 (void) printf(" seq=%" PRIu64
" host=%s\n", betoh64(msg
->dm_count
),
133 main(int argc
, char *argv
[])
141 dlrecv_prog
= basename(argv
[0]);
143 while ((c
= getopt(argc
, argv
, ":s:")) != -1) {
147 sap
= strtoul(optarg
, &eptr
, 10);
148 if (errno
!= 0 || sap
== 0 || sap
>= UINT16_MAX
||
150 dlrecv_usage("Invalid value for sap (-s): %s\n",
157 dlrecv_usage("Option -%c requires an operand\n",
161 dlrecv_usage("Unknown option: -%c\n", optopt
);
170 dlrecv_usage("missing required operands\n");
174 if ((ret
= dlpi_open(argv
[0], &dh
, 0)) != DLPI_SUCCESS
) {
175 warnx("failed to open %s: %s\n", argv
[0],
180 if ((ret
= dlpi_bind(dh
, dlrecv_sap
, &bind_sap
)) != DLPI_SUCCESS
) {
181 warnx("failed to bind to sap 0x%x: %s\n", dlrecv_sap
,
186 if (bind_sap
!= dlrecv_sap
) {
187 warnx("failed to bind to requested sap 0x%x, bound to "
188 "0x%x\n", dlrecv_sap
, bind_sap
);
193 dlpi_recvinfo_t rinfo
;
196 boolean_t invalid
= B_FALSE
;
198 msglen
= sizeof (msg
);
199 ret
= dlpi_recv(dh
, NULL
, NULL
, &msg
, &msglen
, -1, &rinfo
);
200 if (ret
!= DLPI_SUCCESS
) {
201 warnx("failed to receive data: %s\n",
206 if (msglen
!= rinfo
.dri_totmsglen
) {
207 warnx("message truncated: expected %ld bytes, "
208 "got %ld\n", sizeof (dlsend_msg_t
),
209 rinfo
.dri_totmsglen
);
213 if (msglen
!= sizeof (msg
)) {
214 warnx("message too short: expected %ld bytes, "
215 "got %ld\n", sizeof (dlsend_msg_t
),
221 invalid
= !dlrecv_isvalid(&msg
);
224 dlrecv_print(&msg
, &rinfo
, invalid
);
227 /* LINTED: E_STMT_NOT_REACHED */