Skip to content

rm3l/service-names-port-numbers

Repository files navigation

Service Names And Port Numbers Lookup

Maven Central License

Build Workflow Deploy Workflow

Fly.io

Docker Stars Docker Pulls

Table of Contents generated with DocToc

Library and microservice for looking up inside the IANA Service Names And Port Numbers Registry records. Written in Kotlin. It supports registering various datasources (IANA, Nmap Services, ...) and allows to lookup service names from port numbers, or vice-versa.

This library is an in-memory database that allows to lookup IANA records based upon certain filters (e.g., service names, ports, transport protocols, ...). It is very lightweight, and allows for million of lookups per second.

By default, the database is automatically fetched from here. But you can optionally provide your own database and parser by specifying a file or a URL where the data can be downloaded from. The server supports non-interrupting updates and can update the database while it is running.

Service names and port numbers are used to distinguish between different services that run over transport protocols such as TCP, UDP, DCCP, and SCTP.

And GraphQL is a data query language allowing clients to define the structure of the data required, and exactly the same structure of the data is returned from the server. It is a strongly typed runtime which allows clients to dictate what data is needed.

Usage

Live Server

A live running version of the GraphQL API is available on Fly.io: https://service-names-port-numbers.fly.dev/graphiql

Note that this API operates entirely from memory, and auto-updates itself every 12 hours.

Using the library

The library is published on Maven Central. So importing it should be straightforward.

Adding the dependency

Maven
<dependency>
  <groupId>org.rm3l</groupId>
  <artifactId>service-names-port-numbers-library</artifactId>
  <version>0.12.2</version>
</dependency>
Gradle
implementation 'org.rm3l:service-names-port-numbers-library:0.12.2'

Usage

This shows the basic usage of the library. Opening a database and querying.

Example with Kotlin:

import org.rm3l.servicenamesportnumbers.ServiceNamesPortNumbersClient
import org.rm3l.servicenamesportnumbers.domain.Record
import org.rm3l.servicenamesportnumbers.domain.RecordFilter
import org.rm3l.servicenamesportnumbers.domain.Protocol

fun main(args: Array<String>) {

    val serviceNamesPortNumbersClient = ServiceNamesPortNumbersClient
        .builder()
        //You may customize other parts here
        .build()
        
    var records = serviceNamesPortNumbersClient.query(443L) //records is a List<Record>
    //Do something with the records
    
    //To benefit from caching, it is recommended you reuse the client instance
    records = serviceNamesPortNumbersClient.query("http")
    
    //You may pass in complex filters
    records = serviceNamesPortNumbersClient.query(
                RecordFilter(
                    ports=listOf(80L, 443L, 2375L),
                    protocols=listOf(Protocol.TCP)))
    
    //Hot-update the database
    serviceNamesPortNumbersClient.updateDatabase(
                oldDatabase = File("/path/to/my/old/iana-database.xml"),
                newDatabase = File("/path/to/my/local/iana-database.xml"))
}

Example with Java:

import org.rm3l.servicenamesportnumbers.ServiceNamesPortNumbersClient;
import org.rm3l.servicenamesportnumbers.domain.*;
import java.util.*;

public class MyService {
    
    public static void main(String... args) {

        final ServiceNamesPortNumbersClient serviceNamesPortNumbersClient = ServiceNamesPortNumbersClient
            .builder()
            //You may customize other parts here
            .build();
        
        List<Record> records = serviceNamesPortNumbersClient.query(443L);
        //Do something with the records
        
        //To benefit from caching, it is recommended you reuse the client instance
        records = serviceNamesPortNumbersClient.query("http");
        
        //You may pass in complex filters
        records = serviceNamesPortNumbersClient.query(
                    new RecordFilter(
                        null,
                        Collections.singletonList(Protocol.TCP),
                        Arrays.asList(80L, 443L, 2375L)));
        
        //Hot-update the database
        serviceNamesPortNumbersClient.updateDatabase(
                (new File("/path/to/my/old/iana-database.xml"),
                new File("/path/to/my/local/iana-database.xml"));
    }
}

Using the server

Downloading and building

You can build the project with the Gradle Wrapper:

./gradlew build

You will then find the artifacts in the sub-projects build directories:

  • library/build/libs : the library code
  • application/build/libs : Spring-Boot sample application, representing the server app

Running the app is as simple as issuing the following command:

java -jar ./application/build/libs/service-names-port-numbers-app-0.12.2.jar

Then navigate to http://localhost:8080/graphiql to start exploring the GraphQL API.

Visit the application/src/main/resources/application.properties file to see which JVM options you can pass to the application. For example, to make the service listen on port 8888 instead, run:

java \
 -Dserver.port=8888 \
 -jar ./application/build/libs/service-names-port-numbers-app-0.12.2.jar

Querying the GraphQL API

Visit the http://localhost:8080/graphiql to start exploring the GraphQL schema and get completion hints with your queries.

Or send a POST request to the /graphql API endpoint to perform requests. Example with curl:

curl -k -i -X POST http://localhost:8080/graphql \
  -H'Content-Type: application/json' \
  -d '{"query":"{records(filter: {ports: [80, 443, 2375], protocols: [TCP]}) {serviceName portNumber description assignmentNotes}}"}'

HTTP/1.1 200 
X-Application-Context: application
Content-Type: application/json;charset=UTF-8
Content-Length: 481
Date: Sun, 03 Dec 2017 22:22:11 GMT

{
 "data": {
   "records": [
     {
       "serviceName":"http",
       "portNumber":80,
       "description":"World Wide Web HTTP",
       "assignmentNotes":"Defined TXT keys: u=<username> p=<password> path=<path to document>"
     },
     {
       "serviceName":"https",
       "portNumber":443,
       "description":"http protocol over TLS/SSL",
       "assignmentNotes":null
     },
     {
       "serviceName":"docker",
       "portNumber":2375,
       "description":"Docker REST API (plain text)",
       "assignmentNotes":null
     }
   ]
 }
}

Docker

A Docker repository with the microservice can be found here: https://hub.docker.com/r/rm3l/service-names-port-numbers/

To fetch the docker image, run:

docker pull rm3l/service-names-port-numbers

To run the server with the default options and expose it on ports 8080 (and port 8081, for the management endpoints), run:

docker run -p 8080:8080 -p 8081:8081 --rm rm3l/service-names-port-numbers

Then open http://localhost:8080/graphiql on your favorite browser, to start exploring the GraphQL API.

In use in the following apps/services

(If you use this library and/or the microservice, please drop me a line at <[email protected]> (or again, fork, modify this file and submit a pull request), so I can list your app(s) here)

Developed by

License

The MIT License (MIT)

Copyright (c) 2017-2020 Armel Soro

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.