#include <arpa/inet.h>
#include <errno.h>
-#include <stdio.h>
-#include <stdio_ext.h>
#include <stdlib.h>
-#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
#include "sd-dhcp-lease.h"
return (int) lease->ntp_size;
}
+int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr) {
+ assert_return(lease, -EINVAL);
+ assert_return(addr, -EINVAL);
+
+ if (lease->sip_size <= 0)
+ return -ENODATA;
+
+ *addr = lease->sip;
+ return (int) lease->sip_size;
+}
+
+int sd_dhcp_lease_get_pop3_server(sd_dhcp_lease *lease, const struct in_addr **addr) {
+ assert_return(lease, -EINVAL);
+ assert_return(addr, -EINVAL);
+
+ if (lease->pop3_server_size <= 0)
+ return -ENODATA;
+
+ *addr = lease->pop3_server;
+ return (int) lease->pop3_server_size;
+}
+
+int sd_dhcp_lease_get_smtp_server(sd_dhcp_lease *lease, const struct in_addr **addr) {
+ assert_return(lease, -EINVAL);
+ assert_return(addr, -EINVAL);
+
+ if (lease->smtp_server_size <= 0)
+ return -ENODATA;
+
+ *addr = lease->smtp_server;
+ return (int) lease->smtp_server_size;
+}
+
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) {
assert_return(lease, -EINVAL);
assert_return(domainname, -EINVAL);
free(lease->domainname);
free(lease->dns);
free(lease->ntp);
+ free(lease->sip);
+ free(lease->pop3_server);
+ free(lease->smtp_server);
free(lease->static_route);
free(lease->client_id);
free(lease->vendor_specific);
if (memchr(option, 0, len - 1))
return -EINVAL;
- string = strndup((const char *) option, len);
+ string = memdup_suffix0((const char *) option, len);
if (!string)
return -ENOMEM;
return 0;
}
+static int lease_parse_sip_server(const uint8_t *option, size_t len, struct in_addr **ret, size_t *n_ret) {
+ assert(option);
+ assert(ret);
+ assert(n_ret);
+
+ if (len <= 0) {
+ *ret = mfree(*ret);
+ *n_ret = 0;
+ } else {
+ size_t n_addresses;
+ struct in_addr *addresses;
+ int l = len - 1;
+
+ if (l % 4 != 0)
+ return -EINVAL;
+
+ n_addresses = l / 4;
+
+ addresses = newdup(struct in_addr, option + 1, n_addresses);
+ if (!addresses)
+ return -ENOMEM;
+
+ free(*ret);
+ *ret = addresses;
+ *n_ret = n_addresses;
+ }
+
+ return 0;
+}
+
static int lease_parse_routes(
const uint8_t *option, size_t len,
struct sd_dhcp_route **routes, size_t *routes_size, size_t *routes_allocated) {
log_debug_errno(r, "Failed to parse NTP server, ignoring: %m");
break;
+ case SD_DHCP_OPTION_SIP_SERVER:
+ r = lease_parse_sip_server(option, len, &lease->sip, &lease->sip_size);
+ if (r < 0)
+ log_debug_errno(r, "Failed to parse SIP server, ignoring: %m");
+ break;
+
+ case SD_DHCP_OPTION_POP3_SERVER:
+ r = lease_parse_in_addrs(option, len, &lease->pop3_server, &lease->pop3_server_size);
+ if (r < 0)
+ log_debug_errno(r, "Failed to parse POP3 server, ignoring: %m");
+ break;
+
+ case SD_DHCP_OPTION_SMTP_SERVER:
+ r = lease_parse_in_addrs(option, len, &lease->smtp_server, &lease->smtp_server_size);
+ if (r < 0)
+ log_debug_errno(r, "Failed to parse SMTP server, ignoring: %m");
+ break;
+
case SD_DHCP_OPTION_STATIC_ROUTE:
r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, &lease->static_route_allocated);
if (r < 0)
const struct in_addr *addresses;
const void *client_id, *data;
size_t client_id_len, data_len;
+ char sbuf[INET_ADDRSTRLEN];
const char *string;
uint16_t mtu;
_cleanup_free_ sd_dhcp_route **routes = NULL;
if (r < 0)
goto fail;
- (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
(void) fchmod(fileno(f), 0644);
fprintf(f,
r = sd_dhcp_lease_get_address(lease, &address);
if (r >= 0)
- fprintf(f, "ADDRESS=%s\n", inet_ntoa(address));
+ fprintf(f, "ADDRESS=%s\n", inet_ntop(AF_INET, &address, sbuf, sizeof(sbuf)));
r = sd_dhcp_lease_get_netmask(lease, &address);
if (r >= 0)
- fprintf(f, "NETMASK=%s\n", inet_ntoa(address));
+ fprintf(f, "NETMASK=%s\n", inet_ntop(AF_INET, &address, sbuf, sizeof(sbuf)));
r = sd_dhcp_lease_get_router(lease, &addresses);
if (r > 0) {
r = sd_dhcp_lease_get_server_identifier(lease, &address);
if (r >= 0)
- fprintf(f, "SERVER_ADDRESS=%s\n", inet_ntoa(address));
+ fprintf(f, "SERVER_ADDRESS=%s\n", inet_ntop(AF_INET, &address, sbuf, sizeof(sbuf)));
r = sd_dhcp_lease_get_next_server(lease, &address);
if (r >= 0)
- fprintf(f, "NEXT_SERVER=%s\n", inet_ntoa(address));
+ fprintf(f, "NEXT_SERVER=%s\n", inet_ntop(AF_INET, &address, sbuf, sizeof(sbuf)));
r = sd_dhcp_lease_get_broadcast(lease, &address);
if (r >= 0)
- fprintf(f, "BROADCAST=%s\n", inet_ntoa(address));
+ fprintf(f, "BROADCAST=%s\n", inet_ntop(AF_INET, &address, sbuf, sizeof(sbuf)));
r = sd_dhcp_lease_get_mtu(lease, &mtu);
if (r >= 0)
fputc('\n', f);
}
+ r = sd_dhcp_lease_get_sip(lease, &addresses);
+ if (r > 0) {
+ fputs("SIP=", f);
+ serialize_in_addrs(f, addresses, r, false, NULL);
+ fputc('\n', f);
+ }
+
r = sd_dhcp_lease_get_domainname(lease, &string);
if (r >= 0)
fprintf(f, "DOMAINNAME=%s\n", string);
*broadcast = NULL,
*dns = NULL,
*ntp = NULL,
+ *sip = NULL,
+ *pop3_server = NULL,
+ *smtp_server = NULL,
*mtu = NULL,
*routes = NULL,
*domains = NULL,
"BROADCAST", &broadcast,
"DNS", &dns,
"NTP", &ntp,
+ "SIP", &sip,
+ "POP3_SERVERS", &pop3_server,
+ "SMTP_SERVERS", &smtp_server,
"MTU", &mtu,
"DOMAINNAME", &lease->domainname,
"HOSTNAME", &lease->hostname,
lease->ntp_size = r;
}
+ if (sip) {
+ r = deserialize_in_addrs(&lease->sip, sip);
+ if (r < 0)
+ log_debug_errno(r, "Failed to deserialize SIP servers %s, ignoring: %m", sip);
+ else
+ lease->sip_size = r;
+ }
+
+ if (pop3_server) {
+ r = deserialize_in_addrs(&lease->pop3_server, pop3_server);
+ if (r < 0)
+ log_debug_errno(r, "Failed to deserialize POP3 server %s, ignoring: %m", pop3_server);
+ else
+ lease->pop3_server_size = r;
+ }
+
+ if (smtp_server) {
+ r = deserialize_in_addrs(&lease->smtp_server, smtp_server);
+ if (r < 0)
+ log_debug_errno(r, "Failed to deserialize SMTP server %s, ignoring: %m", smtp_server);
+ else
+ lease->smtp_server_size = r;
+ }
+
if (mtu) {
r = safe_atou16(mtu, &lease->mtu);
if (r < 0)