ssize_t send_packet(struct interface_info *interface, struct dhcp_packet *raw, size_t len, struct in_addr from, struct sockaddr_in *to, struct hardware *hto) { unsigned char buf[256]; struct iovec iov[2]; int result, bufp = 0; if (interface->hw_address.htype == HTYPE_IPSEC_TUNNEL) { socklen_t slen = sizeof(*to); result = sendto(server_fd, raw, len, 0, (struct sockaddr *)to, slen); goto done; } /* Assemble the headers... */ assemble_hw_header(interface, buf, &bufp, hto); assemble_udp_ip_header(interface, buf, &bufp, from.s_addr, to->sin_addr.s_addr, to->sin_port, (unsigned char *)raw, len); /* Fire it off */ iov[0].iov_base = (char *)buf; iov[0].iov_len = bufp; iov[1].iov_base = (char *)raw; iov[1].iov_len = len; result = writev(interface->wfdesc, iov, 2); done: if (result == -1) warning("send_packet: %m"); return (result); }
ssize_t send_packet(struct interface_info *interface, struct dhcp_packet *raw, size_t len, struct in_addr from, struct sockaddr_in *to, struct hardware *hto) { unsigned char buf[256]; struct iovec iov[2]; struct msghdr msg; int result, bufp = 0; /* Assemble the headers... */ if (to->sin_addr.s_addr == INADDR_BROADCAST) assemble_hw_header(interface, buf, &bufp, hto); assemble_udp_ip_header(buf, &bufp, from.s_addr, to->sin_addr.s_addr, to->sin_port, (unsigned char *)raw, len); iov[0].iov_base = (char *)buf; iov[0].iov_len = bufp; iov[1].iov_base = (char *)raw; iov[1].iov_len = len; /* Fire it off */ if (to->sin_addr.s_addr == INADDR_BROADCAST) result = writev(interface->wfdesc, iov, 2); else { memset(&msg, 0, sizeof(msg)); msg.msg_name = (struct sockaddr *)to; msg.msg_namelen = sizeof(*to); msg.msg_iov = iov; msg.msg_iovlen = 2; result = sendmsg(interface->ufdesc, &msg, 0); } if (result < 0) warning("send_packet: %m"); return (result); }