Add a utility class for associating IP addresses with ASNs.

This commit is contained in:
Jon Chambers 2021-04-23 17:15:53 -04:00 committed by Jon Chambers
parent 3056ea8cbc
commit 1160af9522
4 changed files with 126 additions and 0 deletions

View File

@ -163,6 +163,12 @@
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>

View File

@ -0,0 +1,80 @@
/*
* Copyright 2021 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.util;
import com.google.common.annotations.VisibleForTesting;
import java.io.IOException;
import java.io.Reader;
import java.net.Inet4Address;
import java.nio.ByteBuffer;
import java.util.NavigableMap;
import java.util.Optional;
import java.util.TreeMap;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
/**
* Allows IP->ASN lookup operations using data from https://iptoasn.com/.
*/
class AsnTable {
private final NavigableMap<Long, AsnRange> asnBlocksByFirstIp;
private static class AsnRange {
private final long rangeStart;
private final long rangeEnd;
private final long asn;
private AsnRange(long rangeStart, long rangeEnd, long asn) {
this.rangeStart = rangeStart;
this.rangeEnd = rangeEnd;
this.asn = asn;
}
boolean contains(final long address) {
return address >= rangeStart && address <= rangeEnd;
}
long getAsn() {
return asn;
}
}
public AsnTable(final Reader tsvReader) throws IOException {
final TreeMap<Long, AsnRange> treeMap = new TreeMap<>();
try (final CSVParser csvParser = CSVFormat.TDF.parse(tsvReader)) {
for (final CSVRecord record : csvParser) {
final long start = Long.parseLong(record.get(0), 10);
final long end = Long.parseLong(record.get(1), 10);
final long asn = Long.parseLong(record.get(2), 10);
treeMap.put(start, new AsnRange(start, end, asn));
}
}
asnBlocksByFirstIp = treeMap;
}
public Optional<Long> getAsn(final Inet4Address address) {
final long addressAsLong = ipToLong(address);
return Optional.ofNullable(asnBlocksByFirstIp.floorEntry(addressAsLong))
.filter(entry -> entry.getValue().contains(addressAsLong))
.map(entry -> entry.getValue().getAsn());
}
@VisibleForTesting
static long ipToLong(final Inet4Address address) {
final ByteBuffer buffer = ByteBuffer.allocate(8);
buffer.position(4);
buffer.put(address.getAddress());
buffer.flip();
return buffer.getLong();
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2021 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.util;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Inet4Address;
import java.net.UnknownHostException;
import java.util.Optional;
import java.util.zip.GZIPInputStream;
import static org.junit.jupiter.api.Assertions.*;
class AsnTableTest {
@Test
void getAsn() throws IOException {
try (final InputStreamReader reader = new InputStreamReader(getClass().getResourceAsStream("ip2asn-test.tsv"))) {
final AsnTable asnTable = new AsnTable(reader);
assertEquals(Optional.of(7922L), asnTable.getAsn((Inet4Address) Inet4Address.getByName("50.79.54.1")));
assertEquals(Optional.of(7552L), asnTable.getAsn((Inet4Address) Inet4Address.getByName("27.79.32.1")));
assertEquals(Optional.empty(), asnTable.getAsn((Inet4Address) Inet4Address.getByName("32.79.117.1")));
assertEquals(Optional.empty(), asnTable.getAsn((Inet4Address) Inet4Address.getByName("10.0.0.1")));
}
}
@Test
void ipToLong() throws UnknownHostException {
assertEquals(0x00000000ffffffffL, AsnTable.ipToLong((Inet4Address) Inet4Address.getByName("255.255.255.255")));
assertEquals(0x0000000000000001L, AsnTable.ipToLong((Inet4Address) Inet4Address.getByName("0.0.0.1")));
}
}

View File

@ -0,0 +1,2 @@
458051584 458227711 7552 VN VIETEL-AS-AP Viettel Group
843841536 844103679 7922 US COMCAST-7922 - Comcast Cable Communications, LLC
1 458051584 458227711 7552 VN VIETEL-AS-AP Viettel Group
2 843841536 844103679 7922 US COMCAST-7922 - Comcast Cable Communications, LLC