Github user cgivre commented on a diff in the pull request:
https://github.com/apache/drill/pull/971#discussion_r146263421
--- Diff:
exec/java-exec/src/main/java/org/apache/drill/exec/expr/fn/impl/NetworkFunctions.java
---
@@ -0,0 +1,566 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.drill.exec.expr.fn.impl;
+
+import io.netty.buffer.DrillBuf;
+import org.apache.drill.exec.expr.DrillSimpleFunc;
+import org.apache.drill.exec.expr.annotations.FunctionTemplate;
+import org.apache.drill.exec.expr.annotations.Output;
+import org.apache.drill.exec.expr.annotations.Param;
+import org.apache.drill.exec.expr.holders.BigIntHolder;
+import org.apache.drill.exec.expr.holders.BitHolder;
+import org.apache.drill.exec.expr.holders.VarCharHolder;
+
+import javax.inject.Inject;
+
+public class NetworkFunctions {
+ static final org.slf4j.Logger logger =
org.slf4j.LoggerFactory.getLogger(NetworkFunctions.class);
+
+ private NetworkFunctions() {
+ }
+
+ /**
+ * This function takes two arguments, an input IPv4 and a CIDR, and
returns true if the IP is in the given CIDR block
+ */
+ @FunctionTemplate(name = "in_network", scope =
FunctionTemplate.FunctionScope.SIMPLE, nulls =
FunctionTemplate.NullHandling.NULL_IF_NULL)
+ public static class InNetworkFunction implements DrillSimpleFunc {
+
+ @Param
+ VarCharHolder inputIP;
+
+ @Param
+ VarCharHolder inputCIDR;
+
+ @Output
+ BitHolder out;
+
+ @Inject
+ DrillBuf buffer;
+
+ public void setup() {
+ }
+
+
+ public void eval() {
+
+ String ipString =
org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputIP.start,
inputIP.end, inputIP.buffer);
+ String cidrString =
org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputCIDR.start,
inputCIDR.end, inputCIDR.buffer);
+
+ int result = 0;
+ org.apache.commons.net.util.SubnetUtils utils = new
org.apache.commons.net.util.SubnetUtils(cidrString);
+
+ if (utils.getInfo().isInRange(ipString)) {
+ result = 1;
+ }
+
+ out.value = result;
+ }
+ }
+
+
+ /**
+ * This function retunrs the number of IP addresses in the input CIDR
block.
+ */
+ @FunctionTemplate(name = "address_count", scope =
FunctionTemplate.FunctionScope.SIMPLE, nulls =
FunctionTemplate.NullHandling.NULL_IF_NULL)
+ public static class AddressCountFunction implements DrillSimpleFunc {
+
+ @Param
+ VarCharHolder inputCIDR;
+
+ @Output
+ BigIntHolder out;
+
+ @Inject
+ DrillBuf buffer;
+
+ public void setup() {
+ }
+
+ public void eval() {
+
+ String cidrString =
org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputCIDR.start,
inputCIDR.end, inputCIDR.buffer);
+ org.apache.commons.net.util.SubnetUtils utils = new
org.apache.commons.net.util.SubnetUtils(cidrString);
+
+ out.value = utils.getInfo().getAddressCount();
+
+ }
+
+ }
+
+ /**
+ * This function returns the broadcast address of a given CIDR block.
+ */
+ @FunctionTemplate(name = "broadcast_address", scope =
FunctionTemplate.FunctionScope.SIMPLE, nulls =
FunctionTemplate.NullHandling.NULL_IF_NULL)
+ public static class BroadcastAddressFunction implements DrillSimpleFunc {
+
+ @Param
+ VarCharHolder inputCIDR;
+
+ @Output
+ VarCharHolder out;
+
+ @Inject
+ DrillBuf buffer;
+
+ public void setup() {
+ }
+
+ public void eval() {
+
+ String cidrString =
org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputCIDR.start,
inputCIDR.end, inputCIDR.buffer);
+ org.apache.commons.net.util.SubnetUtils utils = new
org.apache.commons.net.util.SubnetUtils(cidrString);
+
+ String outputValue = utils.getInfo().getBroadcastAddress();
+
+ out.buffer = buffer;
+ out.start = 0;
+ out.end = outputValue.getBytes().length;
+ buffer.setBytes(0, outputValue.getBytes());
+
+ }
+
+ }
+
+ /**
+ * This function gets the netmask of the input CIDR block.
+ */
+
+ @FunctionTemplate(name = "netmask", scope =
FunctionTemplate.FunctionScope.SIMPLE, nulls =
FunctionTemplate.NullHandling.NULL_IF_NULL)
+ public static class NetmaskFunction implements DrillSimpleFunc {
+
+ @Param
+ VarCharHolder inputCIDR;
+
+ @Output
+ VarCharHolder out;
+
+ @Inject
+ DrillBuf buffer;
+
+ public void setup() {
+ }
+
+ public void eval() {
+
+ String cidrString =
org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputCIDR.start,
inputCIDR.end, inputCIDR.buffer);
+ org.apache.commons.net.util.SubnetUtils utils = new
org.apache.commons.net.util.SubnetUtils(cidrString);
+
+ String outputValue = utils.getInfo().getNetmask();
+
+ out.buffer = buffer;
+ out.start = 0;
+ out.end = outputValue.getBytes().length;
+ buffer.setBytes(0, outputValue.getBytes());
+
+ }
+
+ }
+
+ /**
+ * This function gets the numerically lowest IP address in an input CIDR
block.
+ */
+ @FunctionTemplate(name = "low_address", scope =
FunctionTemplate.FunctionScope.SIMPLE, nulls =
FunctionTemplate.NullHandling.NULL_IF_NULL)
+ public static class LowAddressFunction implements DrillSimpleFunc {
+
+ @Param
+ VarCharHolder inputCIDR;
+
+ @Output
+ VarCharHolder out;
+
+ @Inject
+ DrillBuf buffer;
+
+ public void setup() {
+ }
+
+ public void eval() {
+
+ String cidrString =
org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputCIDR.start,
inputCIDR.end, inputCIDR.buffer);
+ org.apache.commons.net.util.SubnetUtils utils = new
org.apache.commons.net.util.SubnetUtils(cidrString);
+
+ String outputValue = utils.getInfo().getLowAddress();
+
+ out.buffer = buffer;
+ out.start = 0;
+ out.end = outputValue.getBytes().length;
+ buffer.setBytes(0, outputValue.getBytes());
+
+ }
+
+ }
+
+ /**
+ * This function gets the numerically highest IP address in an input
CIDR block.
+ */
+ @FunctionTemplate(name = "high_address", scope =
FunctionTemplate.FunctionScope.SIMPLE, nulls =
FunctionTemplate.NullHandling.NULL_IF_NULL)
+ public static class HighAddressFunction implements DrillSimpleFunc {
+
+ @Param
+ VarCharHolder inputCIDR;
+
+ @Output
+ VarCharHolder out;
+
+ @Inject
+ DrillBuf buffer;
+
+ public void setup() {
+ }
+
+ public void eval() {
+
+ String cidrString =
org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputCIDR.start,
inputCIDR.end, inputCIDR.buffer);
+ org.apache.commons.net.util.SubnetUtils utils = new
org.apache.commons.net.util.SubnetUtils(cidrString);
+
+ String outputValue = utils.getInfo().getHighAddress();
+
+ out.buffer = buffer;
+ out.start = 0;
+ out.end = outputValue.getBytes().length;
+ buffer.setBytes(0, outputValue.getBytes());
+
+ }
+ }
+
+ /**
+ * This function encodes URL strings.
+ */
+ @FunctionTemplate(name = "url_encode", scope =
FunctionTemplate.FunctionScope.SIMPLE, nulls =
FunctionTemplate.NullHandling.NULL_IF_NULL)
+ public static class urlencodeFunction implements DrillSimpleFunc {
+
+ @Param
+ VarCharHolder inputString;
+
+ @Output
+ VarCharHolder outputString;
+
+ @Inject
+ DrillBuf buffer;
+
+ public void setup() {
+ }
+
+ public void eval() {
+
+ String url =
org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputString.start,
inputString.end, inputString.buffer);
+
+ String outputValue = "";
+ try {
+ outputValue = java.net.URLEncoder.encode(url, "UTF-8");
+ } catch (Exception e) {
+
+ }
+ outputString.buffer = buffer;
+ outputString.start = 0;
+ outputString.end = outputValue.getBytes().length;
+ buffer.setBytes(0, outputValue.getBytes());
+
+ }
+ }
+
+ /**
+ * This function decodes URL strings.
+ */
+ @FunctionTemplate(name = "url_decode", scope =
FunctionTemplate.FunctionScope.SIMPLE, nulls =
FunctionTemplate.NullHandling.NULL_IF_NULL)
+ public static class urldecodeFunction implements DrillSimpleFunc {
+
+ @Param
+ VarCharHolder inputString;
+
+ @Output
+ VarCharHolder outputString;
+
+ @Inject
+ DrillBuf buffer;
+
+ public void setup() {
+ }
+
+ public void eval() {
+
+ String url =
org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputString.start,
inputString.end, inputString.buffer);
+
+ String outputValue = "";
+ try {
+ outputValue = java.net.URLDecoder.decode(url, "UTF-8");
+ } catch (Exception e) {
+
+ }
+ outputString.buffer = buffer;
+ outputString.start = 0;
+ outputString.end = outputValue.getBytes().length;
+ buffer.setBytes(0, outputValue.getBytes());
+
+ }
+ }
+
+
+ /**
+ * This function converts a BigInt IPv4 into dotted decimal notation.
The opposite of inet_aton.
+ */
+
+ @FunctionTemplate(name = "inet_ntoa", scope =
FunctionTemplate.FunctionScope.SIMPLE, nulls =
FunctionTemplate.NullHandling.NULL_IF_NULL)
+ public static class InetNtoaFunction implements DrillSimpleFunc {
+
+ @Param
+ BigIntHolder in;
+
+ @Output
+ VarCharHolder out;
+
+ @Inject
+ DrillBuf buffer;
+
+
+ public void setup() {
+ }
+
+
+ public void eval() {
+ StringBuilder result = new StringBuilder(15);
+
+ long inputInt = in.value;
+
+ for (int i = 0; i < 4; i++) {
+
+ result.insert(0, Long.toString(inputInt & 0xff));
+
+ if (i < 3) {
+ result.insert(0, '.');
+ }
+
+ inputInt = inputInt >> 8;
+ }
+
+ String outputValue = result.toString();
+
+ out.buffer = buffer;
+ out.start = 0;
+ out.end = outputValue.getBytes().length;
+ buffer.setBytes(0, outputValue.getBytes());
+ }
+
+
+ }
+
+ /**
+ * This function returns true if a given IPv4 address is private, false
if not.
+ */
+
+ @FunctionTemplate(name = "is_private_ip", scope =
FunctionTemplate.FunctionScope.SIMPLE, nulls =
FunctionTemplate.NullHandling.NULL_IF_NULL)
+ public static class IsPrivateIP implements DrillSimpleFunc {
+
+ @Param
+ VarCharHolder inputTextA;
+
+ @Output
+ BitHolder out;
+
+ @Inject
+ DrillBuf buffer;
+
+
+ public void setup() {
+ }
+
+
+ public void eval() {
+ String ipString =
org.apache.drill.exec.expr.fn.impl.StringFunctionHelpers.toStringFromUTF8(inputTextA.start,
inputTextA.end, inputTextA.buffer);
+
+ String[] ipAddressInArray = ipString.split("\\.");
+
+ int result = 0;
+
+ int[] octets = new int[3];
+
+ for (int i = 0; i < 3; i++) {
+ octets[i] = Integer.parseInt(ipAddressInArray[i]);
+ if (octets[i] > 255 || octets[i] < 0) {
--- End diff --
I put that in there to detect invalid IP addresses. I guess we can remove
it.
---