-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow to provide multiple host names #39
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -40,38 +40,74 @@ | |||||||||||
|
||||||||||||
static bool llmnr_ipv6 = false; | ||||||||||||
/* Host name in DNS name format (length octet + name + 0 byte) */ | ||||||||||||
static char llmnr_hostname[LLMNR_LABEL_MAX_SIZE + 2]; | ||||||||||||
#define LLMNR_LABEL_LEN (LLMNR_LABEL_MAX_SIZE + 2) | ||||||||||||
static char** llmnr_hostnames = NULL; | ||||||||||||
size_t llmnr_hostname_count = 0; | ||||||||||||
|
||||||||||||
static void set_hostname(int entry_index, const char *hostname) | ||||||||||||
{ | ||||||||||||
char* entry_llmnr_hostname = NULL; | ||||||||||||
|
||||||||||||
llmnr_hostnames[entry_index] = xzalloc(LLMNR_LABEL_LEN); | ||||||||||||
entry_llmnr_hostname = llmnr_hostnames[entry_index]; | ||||||||||||
|
||||||||||||
entry_llmnr_hostname[0] = (uint8_t)strlen(hostname); | ||||||||||||
strncpy(&entry_llmnr_hostname[1], hostname, LLMNR_LABEL_MAX_SIZE); | ||||||||||||
entry_llmnr_hostname[LLMNR_LABEL_MAX_SIZE + 1] = '\0'; | ||||||||||||
} | ||||||||||||
|
||||||||||||
void llmnr_set_hostname(const char *hostname) | ||||||||||||
{ | ||||||||||||
llmnr_hostname[0] = strlen(hostname); | ||||||||||||
strncpy(&llmnr_hostname[1], hostname, LLMNR_LABEL_MAX_SIZE); | ||||||||||||
llmnr_hostname[LLMNR_LABEL_MAX_SIZE + 1] = '\0'; | ||||||||||||
set_hostname(0, hostname); | ||||||||||||
} | ||||||||||||
|
||||||||||||
void llmnr_init(const char *hostname, bool ipv6) | ||||||||||||
void llmnr_init(const char *hostnames[], size_t hostname_count, bool ipv6) | ||||||||||||
{ | ||||||||||||
llmnr_set_hostname(hostname); | ||||||||||||
size_t i; | ||||||||||||
llmnr_hostname_count = hostname_count; | ||||||||||||
Comment on lines
+66
to
+67
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add an empty line after variable declaration:
Suggested change
|
||||||||||||
llmnr_hostnames = xzalloc(hostname_count); | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should allocate |
||||||||||||
for (i = 0; i < hostname_count; ++i) { | ||||||||||||
set_hostname(i, hostnames[i]); | ||||||||||||
} | ||||||||||||
llmnr_ipv6 = ipv6; | ||||||||||||
} | ||||||||||||
|
||||||||||||
static bool llmnr_name_matches(const uint8_t *query) | ||||||||||||
void llmnr_release(void) | ||||||||||||
{ | ||||||||||||
size_t i; | ||||||||||||
for(i = 0; i < llmnr_hostname_count; ++i) { | ||||||||||||
Comment on lines
+77
to
+78
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add an empty line after variable declaration and add a space after the
Suggested change
|
||||||||||||
free(llmnr_hostnames[i]); | ||||||||||||
} | ||||||||||||
free(llmnr_hostnames); | ||||||||||||
} | ||||||||||||
|
||||||||||||
/* Return the matched name entry (first byte represents the string length) or NULL */ | ||||||||||||
static char *llmnr_name_matches(const uint8_t *query) | ||||||||||||
{ | ||||||||||||
uint8_t n = llmnr_hostname[0]; | ||||||||||||
size_t i; | ||||||||||||
|
||||||||||||
for (i = 0; i < llmnr_hostname_count; ++i) { | ||||||||||||
uint8_t n; | ||||||||||||
n = llmnr_hostnames[i][0]; | ||||||||||||
Comment on lines
+90
to
+91
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Assign this on declaration:
Suggested change
|
||||||||||||
|
||||||||||||
/* length */ | ||||||||||||
if (query[0] != n) | ||||||||||||
continue; | ||||||||||||
/* NULL byte */ | ||||||||||||
if (query[1 + n] != 0) | ||||||||||||
continue; | ||||||||||||
|
||||||||||||
if (strncasecmp((const char *) &query[1], &llmnr_hostnames[i][1], n) == 0) | ||||||||||||
return llmnr_hostnames[i]; | ||||||||||||
} | ||||||||||||
|
||||||||||||
/* length */ | ||||||||||||
if (query[0] != n) | ||||||||||||
return false; | ||||||||||||
/* NULL byte */ | ||||||||||||
if (query[1 + n] != 0) | ||||||||||||
return false; | ||||||||||||
|
||||||||||||
return strncasecmp((const char *)&query[1], &llmnr_hostname[1], n) == 0; | ||||||||||||
return NULL; | ||||||||||||
} | ||||||||||||
|
||||||||||||
static void llmnr_respond(unsigned int ifindex, const struct llmnr_hdr *hdr, | ||||||||||||
const uint8_t *query, size_t query_len, int sock, | ||||||||||||
const struct sockaddr_storage *sst) | ||||||||||||
const struct sockaddr_storage *sst, char* matched_hostname_entry) | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
{ | ||||||||||||
uint16_t qtype, qclass; | ||||||||||||
uint8_t name_len = query[0]; | ||||||||||||
|
@@ -164,7 +200,7 @@ static void llmnr_respond(unsigned int ifindex, const struct llmnr_hdr *hdr, | |||||||||||
|
||||||||||||
/* NAME */ | ||||||||||||
if (i == 0) | ||||||||||||
memcpy(pkt_put(p, llmnr_hostname[0] + 2), llmnr_hostname, llmnr_hostname[0] + 2); | ||||||||||||
memcpy(pkt_put(p, matched_hostname_entry[0] + 2), matched_hostname_entry, matched_hostname_entry[0] + 2); | ||||||||||||
else { | ||||||||||||
/* message compression (RFC 1035, section 4.1.3) */ | ||||||||||||
uint16_t ptr = 0xC000 | (sizeof(*hdr) + query_len); | ||||||||||||
|
@@ -196,6 +232,7 @@ static void llmnr_packet_process(int ifindex, const uint8_t *pktbuf, size_t len, | |||||||||||
const uint8_t *query; | ||||||||||||
size_t query_len; | ||||||||||||
uint8_t name_len; | ||||||||||||
char* matched_hostname_entry; | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
|
||||||||||||
/* Query too short? */ | ||||||||||||
if (len < sizeof(struct llmnr_hdr)) | ||||||||||||
|
@@ -218,8 +255,9 @@ static void llmnr_packet_process(int ifindex, const uint8_t *pktbuf, size_t len, | |||||||||||
return; | ||||||||||||
|
||||||||||||
/* Authoritative? */ | ||||||||||||
if (llmnr_name_matches(query)) | ||||||||||||
llmnr_respond(ifindex, hdr, query, query_len, sock, sst); | ||||||||||||
matched_hostname_entry = llmnr_name_matches(query); | ||||||||||||
if (matched_hostname_entry) | ||||||||||||
llmnr_respond(ifindex, hdr, query, query_len, sock, sst, matched_hostname_entry); | ||||||||||||
} | ||||||||||||
|
||||||||||||
void llmnr_recv(int sock) | ||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -187,7 +187,8 @@ int main(int argc, char **argv) | |||||
int c, ret = -1; | ||||||
long num_arg; | ||||||
bool daemonize = false, ipv6 = false; | ||||||
char *hostname = NULL; | ||||||
char **hostnames = NULL; | ||||||
size_t name_count = 0, name_i = 0; | ||||||
char *iface = NULL; | ||||||
uint16_t port = LLMNR_UDP_PORT; | ||||||
int llmnrd_sock_rtnl = -1; | ||||||
|
@@ -196,6 +197,17 @@ int main(int argc, char **argv) | |||||
|
||||||
setlinebuf(stdout); | ||||||
|
||||||
/* First count given (host)names, if any, to allocate memory */ | ||||||
while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) { | ||||||
if (c == 'H') | ||||||
++name_count; | ||||||
} | ||||||
Comment on lines
+200
to
+204
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't really like the idea of iterating the options twice. But I guess there is no alternative to this :-( |
||||||
|
||||||
if (!name_count) | ||||||
name_count = 1; | ||||||
hostnames = xzalloc(name_count); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should allocate |
||||||
|
||||||
optind = 1; | ||||||
while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) { | ||||||
switch (c) { | ||||||
case 'd': | ||||||
|
@@ -206,7 +218,8 @@ int main(int argc, char **argv) | |||||
log_to_syslog(); | ||||||
break; | ||||||
case 'H': | ||||||
hostname = xstrdup(optarg); | ||||||
hostnames[name_i] = xstrdup(optarg); | ||||||
++name_i; | ||||||
break; | ||||||
case 'i': | ||||||
iface = xstrdup(optarg); | ||||||
|
@@ -236,13 +249,13 @@ int main(int argc, char **argv) | |||||
register_signal(SIGTERM, signal_handler); | ||||||
register_signal(SIGHUP, signal_handler); | ||||||
|
||||||
if (!hostname) { | ||||||
hostname = xzalloc(MAXHOSTNAMELEN); | ||||||
if (gethostname(hostname, MAXHOSTNAMELEN) != 0) { | ||||||
if (name_i == 0) { | ||||||
hostnames[0] = xzalloc(MAXHOSTNAMELEN); | ||||||
if (gethostname(hostnames[0], MAXHOSTNAMELEN) != 0) { | ||||||
log_err("Failed to get hostname"); | ||||||
return EXIT_FAILURE; | ||||||
} | ||||||
hostname[MAXHOSTNAMELEN - 1] = '\0'; | ||||||
hostnames[0][MAXHOSTNAMELEN - 1] = '\0'; | ||||||
|
||||||
llmnrd_fd_hostname = open("/proc/sys/kernel/hostname", O_RDONLY|O_CLOEXEC|O_NDELAY); | ||||||
} | ||||||
|
@@ -257,7 +270,11 @@ int main(int argc, char **argv) | |||||
rm_pid_file = true; | ||||||
} | ||||||
|
||||||
log_info("Starting llmnrd on port %u, hostname %s\n", port, hostname); | ||||||
log_info("Starting llmnrd on port %u. Assigned hostname(s):\n", port); | ||||||
|
||||||
for(name_i = 0; name_i < name_count; ++name_i) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a space after the for keyword:
Suggested change
|
||||||
log_info("%s\n", hostnames[name_i]); | ||||||
|
||||||
if (iface) | ||||||
log_info("Binding to interface %s\n", iface); | ||||||
|
||||||
|
@@ -275,7 +292,7 @@ int main(int argc, char **argv) | |||||
if (llmnrd_sock_rtnl < 0) | ||||||
goto out; | ||||||
|
||||||
llmnr_init(hostname, ipv6); | ||||||
llmnr_init((const char **) hostnames, name_count, ipv6); | ||||||
tklauser marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
ret = iface_init(llmnrd_sock_rtnl, iface, ipv6, &iface_event_handle); | ||||||
if (ret < 0) | ||||||
|
@@ -318,7 +335,7 @@ int main(int argc, char **argv) | |||||
if (llmnrd_sock_ipv6 >= 0 && FD_ISSET(llmnrd_sock_ipv6, &rfds)) | ||||||
llmnr_recv(llmnrd_sock_ipv6); | ||||||
if (llmnrd_fd_hostname >= 0 && FD_ISSET(llmnrd_fd_hostname, &efds)) | ||||||
hostname_change_handle(hostname, MAXHOSTNAMELEN); | ||||||
hostname_change_handle(hostnames[0], MAXHOSTNAMELEN); | ||||||
} | ||||||
} | ||||||
|
||||||
|
@@ -332,7 +349,11 @@ int main(int argc, char **argv) | |||||
close(llmnrd_sock_ipv6); | ||||||
if (llmnrd_sock_ipv4 >= 0) | ||||||
close(llmnrd_sock_ipv4); | ||||||
free(hostname); | ||||||
for(name_i = 0; name_i < name_count; ++name_i) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a space after the
Suggested change
|
||||||
free(hostnames[name_i]); | ||||||
} | ||||||
free(hostnames); | ||||||
llmnr_release(); | ||||||
if (rm_pid_file) | ||||||
unlink(PIDFILE); | ||||||
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make this
static
, it's not used outside the file.