Amuject / Pingus

A simple network ping tool in nodejs. Supports TCP / UDP / ICMP protocol.
https://www.npmjs.com/package/pingus
MIT License
19 stars 3 forks source link

traceroute not working #5

Closed silverbullettruck2001 closed 2 weeks ago

silverbullettruck2001 commented 1 month ago

I am trying to use the traceroute method but no matter what host I specify, it never returns the hops. If I manually call traceroute for the same host through the command line it works correctly.

Below is how I executing it and then below that is the response I get back. Any assistance would be appreciated. Thanks!

  const result = await new pingus.PingICMP({ host: 'google.com', timeout: 500 })
    .on("result", (result) => {
      console.log(result);
    })
    .on("error", (err, result) => {
      throw err;
    })
    .traceroute();
  type: "ping/icmp/traceroute",
  status: "finish",
  host: "google.com",
  ip: {
    label: "142.250.190.110",
  },
  ips: [
    {
      label: "142.250.190.110",
    },
    {
      label: "2607:f8b0:4009:0817:0000:0000:0000:200e",
    },
  ],
  time: 3131,
  ttl: 128,
  bytes: 32,
  hops: [
    {
      status: "timeout",
      ip: null,
      ttl: 1,
    },
    {
      status: "timeout",
      ip: null,
      ttl: 2,
    },
    {
      status: "timeout",
      ip: null,
      ttl: 3,
    },
    {
      status: "timeout",
      ip: null,
      ttl: 4,
    },
    {
      status: "timeout",
      ip: null,
      ttl: 5,
    },
    {
      status: "timeout",
      ip: null,
      ttl: 6,
    },
    {
      status: "reply",
      ip: "142.250.190.110",
      ttl: 7,
    },
  ],
}
wnynya commented 1 month ago

I tried it, and I found traceroute feature not working in Windows. I think it's bug with row-socket dependency module in Windows OS. If you need to use this traceroute feature now, try it in Linux systems or WSL. I'll try to fix it, but I think it seem needs more time to fix.

silverbullettruck2001 commented 1 month ago

I ran the code from linux and I am getting different output, but I don't think it's correct either. I even changed the timeout to 10000 and it still seems to always return time_exceeded.

Also, could the output be changed to allow the hops information to include each hop's RTT so we can see what the time each hop took was?

Lastly, could the ip and ips output be changed so that they contain valid JSON by omitting the IP in each object? You could probably also omit the property name label as well since the object is pretty self-explanatory by just having the actual ip values.

{
  type: 'ping/icmp/traceroute',
  status: 'finish',
  host: 'google.com',
  ip: { IP { label: '34.194.178.110' } },
  ips: [ IP { label: '34.194.178.110' } ],
  time: 30089,
  ttl: 128,
  bytes: 32,
  hops: [
    { status: 'time_exceeded', ip: '172.31.15.208', ttl: 1 },
    { status: 'time_exceeded', ip: '100.64.88.117', ttl: 2 },
    { status: 'timeout', ip: null, ttl: 3 },
    { status: 'timeout', ip: null, ttl: 4 },
    { status: 'timeout', ip: null, ttl: 5 },
    { status: 'time_exceeded', ip: '241.0.12.65', ttl: 6 },
    { status: 'time_exceeded', ip: '242.2.213.49', ttl: 7 },
    { status: 'time_exceeded', ip: '240.0.160.45', ttl: 8 },
    { status: 'time_exceeded', ip: '242.9.230.129', ttl: 9 },
    { status: 'reply', ip: '34.194.178.110', ttl: 10 }
  ]
}
silverbullettruck2001 commented 1 month ago

Here is the same output with the proposed changes. Note that I made the rtt property an array that would list the 3 values that traceroute provides. In the case of timeouts the array would only contain values that were returned. So if 2 of the RTTs timed out then there would only be 1 element in the RTT array for the hop. You can see that some of the arrays are empty and some only have one or two values in the array.

{
  type: 'ping/icmp/traceroute',
  status: 'finish',
  host: 'google.com',
  ip: '34.194.178.110' ,
  ips: [ '34.194.178.110' ],
  time: 30089,
  ttl: 128,
  bytes: 32,
  hops: [
    { status: 'time_exceeded', ip: '172.31.15.208', ttl: 1, rtt: [12] },
    { status: 'time_exceeded', ip: '100.64.88.117', ttl: 2, rtt: [13, 65, 87] },
    { status: 'timeout', ip: null, ttl: 3, rtt: [] },
    { status: 'timeout', ip: null, ttl: 4, rtt: [] },
    { status: 'timeout', ip: null, ttl: 5, rtt: [] },
    { status: 'time_exceeded', ip: '241.0.12.65', ttl: 6, rtt: [18, 17, 61] },
    { status: 'time_exceeded', ip: '242.2.213.49', ttl: 7, rtt: [95, 93] },
    { status: 'time_exceeded', ip: '240.0.160.45', ttl: 8, rtt: [53, 19, 61] },
    { status: 'time_exceeded', ip: '242.9.230.129', ttl: 9, rtt: [53, 16, 80] },
    { status: 'reply', ip: '34.194.178.110', ttl: 10, rtt: [53, 40, 75] }
  ]
}
silverbullettruck2001 commented 1 month ago

@wnynya the proposed rtt array could also be a string array so milliseconds could be added for clarity. Like rtt: ["13ms", "65ms"] if that would be better?

wnynya commented 1 month ago

I think it's better to implement rtt in this form. And I think it's better to put rtt in a millisecond number type for comparison and so on.

rtt: {
  min: 13
  max: 65
  avg: 43
}
wnynya commented 1 month ago

And time_exceeded (not timeout) is normal response. This is because when the ttl value runs out, router returns time_exceeded with it's ip. to we can do with traceroute.

silverbullettruck2001 commented 1 month ago

@wnynya when do you think it will be possible to get these changes implemented?

wnynya commented 1 month ago

in this week. Maybe tomorrow evening.

silverbullettruck2001 commented 1 month ago

in this week. Maybe tomorrow evening.

That's great! Thanks!

wnynya commented 1 month ago

I updated package. now PingResult has toPrimitiveJSON() method to get json with primitive types.

console.log(result);

{
  type: 'ping/tcp',
  status: 'open',
  host: 'localhost',
  ip: IP { label: '127.0.0.1' },
  ips: [ IP { label: '127.0.0.1' } ],
  time: 2,
  port: 22,
  name: 'ssh',
  banner: 'SSH-2.0-OpenSSH_8.9p1 Ubuntu-3'
  toPrimitiveJSON: [Function (anonymous)]
}

console.log(result.toPrimitiveJSON());

{
  type: 'ping/tcp',
  status: 'open',
  host: 'localhost',
  ip: '127.0.0.1',
  ips: '127.0.0.1',
  time: 2,
  port: 22,
  name: 'ssh',
  banner: 'SSH-2.0-OpenSSH_8.9p1 Ubuntu-3'
}

and traceroute has rtt values like

I think it's better to implement rtt in this form. And I think it's better to put rtt in a millisecond number type for comparison and so on.

rtt: {
  min: 13
  max: 65
  avg: 43
}

in this style.

silverbullettruck2001 commented 1 month ago

@wnynya I noticed that your output has ips as a single value, not an array. Does that need to be addressed so that it can contain multiple values? Also, is the rtt present on each hop object in the hops array?

wnynya commented 1 month ago

@silverbullettruck2001 host value is domain, resolve it with dns records. some domains has multiple A records with same domain. so ips has all ip values with host, and ip is selected ip(first value) in ips.

wnynya commented 1 month ago

yes, rtt present time taken with each hop