static int client_receive_message_udp(sd_event_source *s, int fd, uint32_t revents, void *userdata) { sd_dhcp_client *client = userdata; _cleanup_free_ DHCPMessage *message = NULL; int buflen = 0, len, r; assert(s); assert(client); r = ioctl(fd, FIONREAD, &buflen); if (r < 0 || buflen <= 0) buflen = sizeof(DHCPMessage) + DHCP_MIN_OPTIONS_SIZE; message = malloc0(buflen); if (!message) return -ENOMEM; len = read(fd, message, buflen); if (len < 0) { log_dhcp_client(client, "could not receive message from UDP " "socket: %s", strerror(errno)); return 0; } else if ((size_t)len < sizeof(DHCPMessage)) return 0; return client_handle_message(client, message, len); }
static int client_receive_message_udp(sd_event_source *s, int fd, uint32_t revents, void *userdata) { sd_dhcp_client *client = userdata; _cleanup_free_ DHCPMessage *message = NULL; int buflen = 0, len, r; assert(s); assert(client); r = ioctl(fd, FIONREAD, &buflen); if (r < 0) return r; if (buflen < 0) /* this can't be right */ return -EIO; message = malloc0(buflen); if (!message) return -ENOMEM; len = read(fd, message, buflen); if (len < 0) { log_dhcp_client(client, "could not receive message from UDP " "socket: %m"); return 0; } else if ((size_t)len < sizeof(DHCPMessage)) return 0; return client_handle_message(client, message, len); }
static int client_receive_message_raw(sd_event_source *s, int fd, uint32_t revents, void *userdata) { sd_dhcp_client *client = userdata; _cleanup_free_ DHCPPacket *packet = NULL; uint8_t cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))]; struct iovec iov = {}; struct msghdr msg = { .msg_iov = &iov, .msg_iovlen = 1, .msg_control = cmsgbuf, .msg_controllen = sizeof(cmsgbuf), }; struct cmsghdr *cmsg; bool checksum = true; int buflen = 0, len, r; assert(s); assert(client); r = ioctl(fd, FIONREAD, &buflen); if (r < 0 || buflen <= 0) buflen = sizeof(DHCPPacket) + DHCP_MIN_OPTIONS_SIZE; packet = malloc0(buflen); if (!packet) return -ENOMEM; iov.iov_base = packet; iov.iov_len = buflen; len = recvmsg(fd, &msg, 0); if (len < 0) { log_dhcp_client(client, "could not receive message from raw " "socket: %s", strerror(errno)); return 0; } else if ((size_t)len < sizeof(DHCPPacket)) return 0; for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level == SOL_PACKET && cmsg->cmsg_type == PACKET_AUXDATA && cmsg->cmsg_len == CMSG_LEN(sizeof(struct tpacket_auxdata))) { struct tpacket_auxdata *aux = (struct tpacket_auxdata*)CMSG_DATA(cmsg); checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY); break; } } r = dhcp_packet_verify_headers(packet, len, checksum); if (r < 0) return 0; len -= DHCP_IP_UDP_SIZE; return client_handle_message(client, &packet->dhcp, len); } int sd_dhcp_client_start(sd_dhcp_client *client) { int r; assert_return(client, -EINVAL); r = client_initialize(client); if (r < 0) return r; if (client->last_addr) client->state = DHCP_STATE_INIT_REBOOT; r = client_start(client); if (r >= 0) log_dhcp_client(client, "STARTED on ifindex %u with address %s", client->index, ether_ntoa(&client->client_id.mac_addr)); return r; }