Once we open a socket, we probably want to send and receive data across it.Here is the system call we need to make in order to send data as I wrote about in my last post:
c = sendto(sd, buf, sizeof(buf), 0,
(struct sockaddr *)&addr, sizeof(addr));
Note the cast of the addr parameter. This is a structure with another structure embedded in it. I tried hand-jamming the structure, but the data sent across the system call interface was not what I expected. In order to make it work ,I uses a utility called ctypesgen with the header I separated out in my last post. Runing this:
ctypesgen ./spdmcli.h
generates a lot of code, much of which I don’t need. The part I do need looks like this:
__uint8_t = c_ubyte# /usr/include/bits/types.h: 38
__uint16_t = c_ushort# /usr/include/bits/types.h: 40
__uint32_t = c_uint# /usr/include/bits/types.h: 42
uint8_t = __uint8_t# /usr/include/bits/stdint-uintn.h: 24
uint16_t = __uint16_t# /usr/include/bits/stdint-uintn.h: 25
uint32_t = __uint32_t# /usr/include/bits/stdint-uintn.h: 26
# /root/spdmcli/spdmcli.h: 5
class struct_mctp_addr(Structure):
pass
struct_mctp_addr.__slots__ = [
's_addr',
]
struct_mctp_addr._fields_ = [
('s_addr', uint8_t),
]
# /root/spdmcli/spdmcli.h: 9
class struct_sockaddr_mctp(Structure):
pass
struct_sockaddr_mctp.__slots__ = [
'smctp_family',
'smctp_network',
'smctp_addr',
'smctp_type',
'smctp_tag',
]
struct_sockaddr_mctp._fields_ = [
('smctp_family', uint16_t),
('smctp_network', uint32_t),
('smctp_addr', struct_mctp_addr),
('smctp_type', uint8_t),
('smctp_tag', uint8_t),
]
# /root/spdmcli/spdmcli.h: 3
try:
MCTP_TAG_OWNER = 0x08
except:
pass
mctp_addr = struct_mctp_addr# /root/spdmcli/spdmcli.h: 5
sockaddr_mctp = struct_sockaddr_mctp# /root/spdmcli/spdmcli.h: 9
With those definition, the following code makes the system call with the parameter data in the right order:
mctp_addr = struct_mctp_addr(0x32) # /root/spdmcli/spdmcli.h: 16
sockaddr_mctp = struct_sockaddr_mctp(AF_MCTP, 1, mctp_addr , 5, 0x08)
p = create_string_buffer(b"Held")
p[0] = 0x10
p[1] = 0x82
sz = sizeof(sockaddr_mctp)
print("calling sendto")
rc = libc.sendto(sock, p, sizeof(p), 0, byref(sockaddr_mctp), sz)
errno = get_errno_loc()[0]
print("rc = %d errno = %d" % (rc, errno) )
if (rc < 0 ):
exit(rc)
print("OK")
With this Next step is to read the response.