summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMandar Gokhale <mandarg@mandarg.com>2018-09-24 17:57:08 -0400
committerTobias Klauser <tklauser@distanz.ch>2018-10-04 10:21:15 +0200
commitb0ea31142a550167fca9d3590f54439b9d6a3564 (patch)
tree34b7f60ae5147f3ee4ff351ea3ccf2d261446c7e
parent42978816ca573ec4f75e8069bb7891239d703a38 (diff)
mz: Add error handling for mismatched address families
Check for errors in IP addresses specified, and throw an appropriate error if they are not specified properly, e.g. if user uses `-6` option with an IPv4 source address. Closes #166 Signed-off-by: Mandar Gokhale <mandarg@mandarg.com> Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
-rw-r--r--staging/mausezahn.c83
1 files changed, 70 insertions, 13 deletions
diff --git a/staging/mausezahn.c b/staging/mausezahn.c
index 80bfe7d..de3a2e2 100644
--- a/staging/mausezahn.c
+++ b/staging/mausezahn.c
@@ -699,17 +699,45 @@ int getopts (int argc, char *argv[])
(!ipv6_mode && get_ip_range_src(tx.ip_src_txt))
)
{
- // name2addr4 accepts a DOTTED DECIMAL ADDRESS or a FQDN:
- if (ipv6_mode)
- tx.ip6_src = libnet_name2addr6 (l, tx.ip_src_txt, LIBNET_RESOLVE);
- else
- tx.ip_src = libnet_name2addr4 (l, tx.ip_src_txt, LIBNET_RESOLVE);
+ // name2addr{4,6} accepts a valid IP address or a FQDN:
+ if (ipv6_mode) {
+ tx.ip6_src = libnet_name2addr6(l, tx.ip_src_txt, LIBNET_RESOLVE);
+ if (libnet_in6_is_error(tx.ip6_src)) {
+ /* libnet_in6_is_error returns 1 for the valid IPv6 address
+ * ffff:ffff:ffff:ffff:ffff:ffff. Use an additional inet_pton()
+ * check to cover cases where this address is specified
+ * as source
+ */
+ struct in6_addr src_check;
+ if (inet_pton(AF_INET6, tx.ip_src_txt, &src_check) != 1) {
+ fprintf(stderr, "Failed to set source"
+ " IPv6 address. Please check if"
+ " source is set to a valid IPv6 address.\n");
+ return 1;
+ }
+ }
+ } else {
+ tx.ip_src = libnet_name2addr4(l, tx.ip_src_txt, LIBNET_RESOLVE);
+ if (tx.ip_src == -1) {
+ /* libnet_name2addr4() returns -1 for the valid address 255.255.255.255.
+ * Use an additional inet_pton() check to cover case where this address
+ * is specified as source
+ */
+ struct in_addr src_check;
+ if (inet_pton(AF_INET, tx.ip_src_txt, &src_check) != 1) {
+ fprintf(stderr, "Failed to set source"
+ " IPv4 address. Please check if"
+ " source is set to a valid IPv4 address.\n");
+ return 1;
+ }
+ }
+ }
}
- }
- else { // no source IP specified: by default use own IP address
+ } else {
+ // no source IP specified: by default use own IP address
if (ipv6_mode) {
tx.ip6_src = libnet_get_ipaddr6(l);
- if (strncmp((char*)&tx.ip6_src,(char*)&in6addr_error,sizeof(in6addr_error))==0)
+ if (strncmp((char*)&tx.ip6_src,(char*)&in6addr_error, sizeof(in6addr_error))==0)
printf("Failed to set source IPv6 address: %s", l->err_buf);
}
else
@@ -733,11 +761,40 @@ int getopts (int argc, char *argv[])
(ipv6_mode && get_ip6_range_dst(tx.ip_dst_txt, l)) || // returns 1 when no range has been specified
(!ipv6_mode && get_ip_range_dst(tx.ip_dst_txt)))
{
- // name2addr4 accepts a DOTTED DECIMAL ADDRESS or a FQDN:
- if (ipv6_mode)
- tx.ip6_dst = libnet_name2addr6 (l, tx.ip_dst_txt, LIBNET_RESOLVE);
- else
- tx.ip_dst = libnet_name2addr4 (l, tx.ip_dst_txt, LIBNET_RESOLVE);
+ // name2addr{4, 6} accepts a valid IP address or a FQDN:
+ if (ipv6_mode) {
+ tx.ip6_dst = libnet_name2addr6(l, tx.ip_dst_txt, LIBNET_RESOLVE);
+ if (libnet_in6_is_error(tx.ip6_dst)) {
+ /* libnet_in6_is_error returns 1 for the valid IPv6 address
+ * ffff:ffff:ffff:ffff:ffff:ffff. Use an additional inet_pton()
+ * check to cover cases where this address is specified
+ * as destination
+ */
+ struct in6_addr dst_check;
+ if (inet_pton(AF_INET6, tx.ip_dst_txt, &dst_check) != 1) {
+ fprintf(stderr, "Failed to set destination"
+ " IPv6 address. Please check if"
+ " source is set to a valid IPv6 address.\n");
+ return 1;
+ }
+ }
+ } else {
+ tx.ip_dst = libnet_name2addr4(l, tx.ip_dst_txt, LIBNET_RESOLVE);
+ if (tx.ip_dst == -1) {
+ /* libnet_name2addr4() returns -1 for the valid address 255.255.255.255.
+ * Use an additional inet_pton() check to cover case where this address
+ * is specified as destination
+ */
+ struct in_addr dst_check;
+ if (inet_pton(AF_INET, tx.ip_dst_txt, &dst_check) != 1) {
+ fprintf(stderr, "Failed to set destination"
+ " IPv4 address. Please check if"
+ " destination is set to a valid IPv4 address.\n");
+ return 1;
+ }
+ }
+ }
+
}
}
else { // no destination IP specified: by default use broadcast