Skip to content

Commit

Permalink
Added IP details clicking the IP in the list
Browse files Browse the repository at this point in the history
  • Loading branch information
mdima committed May 3, 2024
1 parent f7e0fa3 commit e092c6b
Show file tree
Hide file tree
Showing 13 changed files with 173 additions and 34 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,7 @@ michele73/traceroute:1.1.2
Example:
docker run -d -p 8081:80 --name=traceroute --restart=always -v traecroute_logs:/app/logs michele73/traceroute:1.1.2

The image repository is here: https://hub.docker.com/r/michele73/traceroute

### Live Demo
You can view a live demo of the Trace Route application here: https://traceroute.di-maria.it/
44 changes: 43 additions & 1 deletion TraceRoute/Controllers/APIController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ public async Task<TraceResultViewModel> TraceRoute(string destination)
TraceHop t = new()
{
HopAddress = hopData[1],
TripTime = float.Parse(hopData[2])
TripTime = float.Parse(hopData[2]),
Details = new() {
IsBogonIP = _bogonIPService.IsBogonIP(hopData[1])
}
};
response.Hops.Add(t);
}
Expand Down Expand Up @@ -135,5 +138,44 @@ public async Task<TraceHopDetails> IPInfo(string ipAddress)
}
return result;
}

/// <summary>
/// Retrives the detailed information about the given IP address
/// </summary>
/// <param name="ipAddress">The IP address to request</param>
/// <returns>The IP information</returns>
[HttpGet("api/ipdetails/{ipAddress}")]
public async Task<IpApiResponse> IPDetails(string ipAddress)
{
IpApiResponse result = new();

try
{
_logger.LogDebug("Requested IPDetails for: {0}", ipAddress);

if (!_bogonIPService.IsBogonIP(ipAddress))
{
IpApiResponse? response = await _ipApiClient.Get(ipAddress, new CancellationToken());
if (response != null)
{
result = response;
}
else
{
result.status = "Could not retrive the IP information";
}
}
else
{
result.status = "BogonIP";
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting the IP details: {0}", ipAddress);
result.status = "Error";
}
return result;
}
}
}
23 changes: 2 additions & 21 deletions TraceRoute/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,5 @@ WORKDIR /app
EXPOSE 80
EXPOSE 443

RUN apt-get update \
&& apt-get install -y curl traceroute dnsutils

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["TraceRoute/TraceRoute.csproj", "TraceRoute/"]
RUN dotnet restore "./TraceRoute/TraceRoute.csproj"
COPY . .
WORKDIR "/src/TraceRoute"
RUN dotnet build "./TraceRoute.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./TraceRoute.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
ENV ASPNETCORE_URLS=http://+:80
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "TraceRoute.dll"]
RUN apt-get update
RUN apt-get install -y curl traceroute
19 changes: 17 additions & 2 deletions TraceRoute/Models/IpApiResponse.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
namespace TraceRoute.Models
using System.Text.Json.Serialization;

namespace TraceRoute.Models
{
public class IpApiResponse
{
public string? query { get; set; }
public string? status { get; set; }
public string? continent { get; set; }
public string? continentCode { get; set; }
public string? country { get; set; }
public string? countryCode { get; set; }
public string? region { get; set; }
public string? regionName { get; set; }
public string? city { get; set; }
public string? district { get; set; }
public string? zip { get; set; }
public double? lat { get; set; }
public double? lon { get; set; }
public string? timezone { get; set; }
public double? offset { get; set; }
public string? currency { get; set; }
public string? isp { get; set; }
public string? query { get; set; }
public string? org { get; set; }
[JsonPropertyName("as")]
public string? _as { get; set; }
public string? asname { get; set; }
public bool? mobile { get; set; }
public bool? proxy { get; set; }
public bool? hosting { get; set; }
}
}
2 changes: 1 addition & 1 deletion TraceRoute/Services/IpApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class IpApiClient(HttpClient httpClient, ILogger<IpApiClient> logger, IMe
if (response == null)
{
_logger.LogDebug("Asking the IP information for IP: {0}", ipAddress);
string route = $"{BASE_URL}/json/{ipAddress}";
string route = $"{BASE_URL}/json/{ipAddress}?fields=status,message,continent,continentCode,country,countryCode,region,regionName,city,district,zip,lat,lon,timezone,offset,currency,isp,org,as,asname,reverse,mobile,proxy,hosting,query";
response = await _httpClient.GetFromJsonAsync<IpApiResponse>(route, ct);
_logger.LogDebug("Result: {0}", JsonConvert.SerializeObject(response));
if (response != null)
Expand Down
8 changes: 6 additions & 2 deletions TraceRoute/Views/Home/About.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
<p>
As default host to trace it will be shown your current public IP address.
</p>
<p>
You can find more information on GitHub in the <a href="https://github.com/mdima/traceroute" target="_blank">project repository</a>.
<p class="mb-0">
For more information you can look at:
</p>
<ul>
<li><a href="https://github.com/mdima/traceroute" target="_blank">GitHub</a> for the source code</li>
<li><a href="https://hub.docker.com/r/michele73/traceroute" target="_blank">Docker Hub</a> for the container repository</li>
</ul>
</div>
8 changes: 7 additions & 1 deletion TraceRoute/Views/Home/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ ViewData["Title"] = "Visual Trace Route";
<tbody>
<tr ng-repeat="hop in vm.HostList track by $index" class="tr_hop_{{$index + 1}}" data-index-value="{{ $index + 1 }}" onmouseover="hilightTooltip(this)">
<td class="ps-2 tr_hop_{{$index + 1}}">{{$index + 1}}</td>
<td class="tr_hop_{{$index + 1}}">{{hop.hopAddress}}
<td class="tr_hop_{{$index + 1}}">
<a href="#" class="link-secondary" ng-click="vm.IpDetails(hop.hopAddress)" ng-show="!hop.details.isBogonIP">
{{hop.hopAddress}}
</a>
<span ng-show="hop.details.isBogonIP">
{{hop.hopAddress}}
</span>
<small ng-show="hop.details.hostName != null" class="small text-muted">
<br />{{hop.details.hostName}}
</small>
Expand Down
39 changes: 39 additions & 0 deletions TraceRoute/Views/Shared/_Layout.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,45 @@
</div>
</div>
</div>
<div class="modal fade" id="modalIpDetails" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLongTitle">IP details for: <strong>{{vm.ipDetail.query}}</strong></h5>
</div>
<div class="modal-body">
<div class="spinner-border spinner-border-lg m-5" role="status" ng-show="vm.ipDetail == null">
<span class="visually-hidden">Loading...</span>
</div>
<div class="row" ng-show="vm.ipDetail != null">
<div class="col-3 HalfStrong" ng-show="vm.ipDetail != null">Continent</div>
<div class="col-9" ng-show="vm.ipDetail != null">{{vm.ipDetail.continent}}</div>
<div class="col-3 HalfStrong" ng-show="vm.ipDetail != null">Country</div>
<div class="col-9" ng-show="vm.ipDetail != null">{{vm.ipDetail.country}} ({{vm.ipDetail.countryCode}})</div>
<div class="col-3 HalfStrong" ng-show="vm.ipDetail != null">Region</div>
<div class="col-9" ng-show="vm.ipDetail != null">{{vm.ipDetail.regionName}} ({{vm.ipDetail.region}})</div>
<div class="col-3 HalfStrong" ng-show="vm.ipDetail != null">City</div>
<div class="col-9" ng-show="vm.ipDetail != null">{{vm.ipDetail.city}} <span ng-show="vm.ipDetail.district"> ({{vm.ipDetail.district}}) </span>- {{vm.ipDetail.zip}}</div>
<div class="col-3 HalfStrong" ng-show="vm.ipDetail != null">ISP</div>
<div class="col-9" ng-show="vm.ipDetail != null">{{vm.ipDetail.isp}}</div>
<div class="col-3 HalfStrong" ng-show="vm.ipDetail != null">Organization</div>
<div class="col-9" ng-show="vm.ipDetail != null">{{vm.ipDetail.org}}</div>
<div class="col-3 HalfStrong" ng-show="vm.ipDetail != null">AS</div>
<div class="col-9" ng-show="vm.ipDetail != null">{{vm.ipDetail.as}} ({{vm.ipDetail.asname}})</div>
<div class="col-3 HalfStrong" ng-show="vm.ipDetail != null">Is mobile</div>
<div class="col-9" ng-show="vm.ipDetail != null">{{vm.ipDetail.mobile}}</div>
<div class="col-3 HalfStrong" ng-show="vm.ipDetail != null">Is proxy</div>
<div class="col-9" ng-show="vm.ipDetail != null">{{vm.ipDetail.proxy}}</div>
<div class="col-3 HalfStrong" ng-show="vm.ipDetail != null">Is hosting</div>
<div class="col-9" ng-show="vm.ipDetail != null">{{vm.ipDetail.hosting}}</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" ng-click="vm.closeModalIpDetails()">Close</button>
</div>
</div>
</div>
</div>
<script src="~/lib/jquery/jquery.min.js" asp-append-version="true"></script>
<script src="~/lib/twitter-bootstrap/js/bootstrap.min.js"></script>
<script src="~/lib/leaflet/leaflet.min.js"></script>
Expand Down
8 changes: 8 additions & 0 deletions TraceRoute/wwwroot/css/site.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@
z-index: 450!important;
}

ul {
margin: 0px
}

.HalfStrong {
font-weight: 400
}

@keyframes highlight {
0% {
background: #ffff99;
Expand Down
2 changes: 1 addition & 1 deletion TraceRoute/wwwroot/css/site.min.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 29 additions & 3 deletions TraceRoute/wwwroot/js/traceRouteController.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
var theResponse;
vm.HostList = [];
vm.isTracing = false;
vm.ipDetail = null;

$(function () {

});
Expand Down Expand Up @@ -73,9 +75,33 @@
);
}

vm.hilightTooltip = function(index) {
alert("index")
console.log("Index: " + index);
vm.IpDetails = function(ipAddress)
{
vm.ipDetail = null;
$('#modalIpDetails').modal('show');
$http.get("api/IPDetails/" + ipAddress)
.then(
function successFunction(response) {
vm.ipDetail = angular.fromJson(response).data;
if (vm.ipDetail.status != "success") {
vm.ErrorDescription = vm.ipDetail.status;
let toastError = bootstrap.Toast.getOrCreateInstance($("#ToastError"));
toastError.show();
$('#modalIpDetails').modal('hide');
}
}
)
.catch((err) => {
vm.ErrorDescription = "Could not retrive the IP information";
let toastError = bootstrap.Toast.getOrCreateInstance($("#ToastError"));
toastError.show();
console.error('An error occurred:', err);
});
}

vm.closeModalIpDetails = function (ipAddress) {
vm.ipDetail = null;
$('#modalIpDetails').modal('hide');
}
};
})();
16 changes: 16 additions & 0 deletions UnitTests/Controllers/APIControllerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,21 @@ public async Task SecurityChecks()
TraceHopDetails hopResponse = await _controller.IPInfo("ls /");
Assert.AreEqual("Could not retrive the IP information", hopResponse.ErrorDescription);
}

[TestMethod]
public async Task IPDetails()
{
IpApiResponse response = await _controller.IPDetails("192.188.248.215");

Assert.AreEqual("192.188.248.215", response.query);
Assert.AreEqual("success", response.status);
Assert.AreEqual("Milan", response.city);

response = await _controller.IPDetails("errorgen");
Assert.AreEqual("Could not retrive the IP information", response.status);

response = await _controller.IPDetails("10.0.0.1");
Assert.AreEqual("BogonIP", response.status);
}
}
}
4 changes: 2 additions & 2 deletions UnitTests/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ WORKDIR /app
EXPOSE 80
EXPOSE 443

RUN apt-get update \
&& apt-get install -y curl traceroute
RUN apt-get update
RUN apt-get install -y curl traceroute dnsutils

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
Expand Down

0 comments on commit e092c6b

Please sign in to comment.