aboutsummaryrefslogtreecommitdiffstats
path: root/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/network/IPVersion.java
blob: b4ebb1bc5723494b366652f54baa555523cd4cba (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.node.admin.task.util.network;

import com.google.common.net.InetAddresses;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Strong type IPv4 and IPv6 with common executables for ip related commands.
 *
 * @author smorgrav
 */
public enum IPVersion {

    IPv6(6, "ip6tables", "ip -6", "ipv6-icmp", 128, "icmp6-port-unreachable", "ip6tables-restore", "fe80::/10"),
    IPv4(4, "iptables", "ip", "icmp", 32, "icmp-port-unreachable", "iptables-restore", "169.254.0.0/16");

    private static final Pattern cidrNotationPattern = Pattern.compile("/\\d+$");

    IPVersion(int version, String iptablesCmd, String ipCmd,
              String icmpProtocol, int size, String icmpPortUnreachable,
              String iptablesRestore, String linkLocalCidr) {
        this.version = version;
        this.ipCmd = ipCmd;
        this.iptablesCmd = iptablesCmd;
        this.icmpProtocol = icmpProtocol;
        this.size = size;
        this.icmpPortUnreachable = icmpPortUnreachable;
        this.iptablesRestore = iptablesRestore;
        this.linkLocalCidr = linkLocalCidr;
    }

    private final int version;
    private final String iptablesCmd;
    private final String ipCmd;
    private final String icmpProtocol;
    private final int size;
    private final String icmpPortUnreachable;
    private final String iptablesRestore;
    private final String linkLocalCidr;

    /** The ID of the IP version, either IPv4 or IPv6. */
    public String id() { return "IPv" + version; }

    /** The IP version, either 4 or 6 */
    public int version() { return version; }

    public String versionString() { return String.valueOf(version); }
    public String iptablesCmd() { return iptablesCmd; }
    public String iptablesRestore() { return iptablesRestore;}
    public String ipCmd() { return ipCmd; }
    public String icmpProtocol() { return icmpProtocol; }
    public String singleHostCidr() { return "/" + size; }
    public String icmpPortUnreachable() { return icmpPortUnreachable; }

    /** The address size (in bits) of the IP version: 32 or 128. */
    public int addressSize() { return size; }

    /** Both IPv4 and IPv6 have exactly one link-local address space: 169.254.0.0/16 or fe80::/10. */
    public String linkLocalAddressCidr() { return linkLocalCidr; }

    public boolean match(InetAddress address) {
        return this == IPVersion.get(address);
    }

    public boolean match(String address) {
        return this == IPVersion.get(address);
    }

    public static IPVersion get(String address) {
        Matcher matcher = cidrNotationPattern.matcher(address);
        if (matcher.find()) {
            address = matcher.replaceFirst("");
        }
        return get(InetAddresses.forString(address));
    }

    public static IPVersion get(InetAddress address) {
        return address instanceof Inet4Address ? IPv4 : IPv6;
    }

}