论坛: 菜鸟乐园 标题: 一个简单的路由跟踪程序 复制本贴地址    
作者: cmark [cmark]    论坛用户   登录
用的是ICMP包,但有的防火墙过滤掉了,采用UDP会更好一点,同时接收包的时候没考虑太多的解码问题,有兴趣的朋友可一改写一个更好的,

/*
 * Copyright 2002 FWSOFT
 * All rights reserved
 *
 * File traceroute.cpp
 * Description a simple traceroute program
 * Programmer CMark
 * Date 1/2/2003
 * Version 0.1
 *
 */

#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include "fwip.h"
#include <winbase.h>
#include <windef.h>

int main(int argc,char** argv)
{
  //check parameter
  if(argc != 2)
  {
  printf("usage: traceroute dest\n");
  return 1;
  }

  //initialize socket library
  WORD versionRequested = MAKEWORD(2,2);
  WSADATA wsaData;
  int err = WSAStartup(versionRequested,&wsaData);
  if(err != 0 )
  {
    printf("socket initialized failed with error %d\n",WSAGetLastError());
    return 1;
  }
  
  hostent* phostent = NULL;
  unsigned long destip = inet_addr(argv[1]);
  if(destip == INADDR_NONE)
  {
  phostent = gethostbyname(argv[1]);
  if(phostent == NULL)
  {
  printf("can not resolve host %s\n",argv[1]);
  return 1;
  }
  memcpy(&destip,phostent->h_addr_list[0],phostent->h_length);
  }

  //create socket
  SOCKET sock = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
  if(sock == INVALID_SOCKET)
  {
    printf("failed to create socket!");
    return 1;
  }

  int timeout = 5000;
  setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout));

  ICMP_ECHO_HEADER icmph;

  //fill icmp header
  icmph.icmp_echo_type = 8; //icmp request
  icmph.icmp_echo_code = 0;
  icmph.icmp_echo_checksum = 0;
  icmph.icmp_echo_identifier = htons(HIWORD(GetCurrentProcessId()));
  icmph.icmp_echo_serial = htons (LOWORD(GetCurrentProcessId()));
  icmph.icmp_echo_checksum = 0;

  char* pbuf = (char *)malloc(sizeof(icmph)+40);
  CopyMemory(pbuf,&icmph,sizeof(icmph));
  char* pdata = pbuf + sizeof(icmph);
  memset((void *)pdata,'E',40);

  USHORT cs = CheckSum((USHORT *)pbuf,sizeof(icmph)+40);
  ICMP_ECHO_HEADER* pheader = (ICMP_ECHO_HEADER *)pbuf;
  pheader->icmp_echo_checksum = cs;

  SOCKADDR_IN addrto;
  addrto.sin_family = AF_INET;
  addrto.sin_addr.S_un.S_addr = destip;
  addrto.sin_port = 0;
  
  char* prbuf = (char *)malloc(1024);
  
  int ttl;
  for(int ii=0; ii<30; ii++)
  {
ttl=ii+1;
setsockopt(sock,IPPROTO_IP,IP_TTL,(const char *)&ttl,sizeof(ttl)); //set ttl
int ret = sendto(sock,pbuf,sizeof(icmph)+40,0,(sockaddr *)&addrto,sizeof(addrto));
if(ret == SOCKET_ERROR)
{
  printf("error send icmp packet with %d\n",WSAGetLastError());
  return 1;
}

SOCKADDR_IN from;
int fromlen = sizeof(from);
ret = recvfrom(sock,prbuf,1024,0,(sockaddr *)&from,&fromlen);
if(ret != SOCKET_ERROR)
{
ICMP_ECHO_HEADER* ph = (ICMP_ECHO_HEADER *)(prbuf+sizeof(IP_HEADER));
IP_HEADER* pip = (IP_HEADER *)prbuf;
if(ph->icmp_echo_type == 11 && ph->icmp_echo_code == 0)
{
printf("router %d --> %s\n",ii+1,inet_ntoa(from.sin_addr));
}
else
{
if(ph->icmp_echo_type == 0)
{
printf("destination %s reached\n",argv[1]);
break;
}
}
}
else //timeout 
{
break;
}
  }

  //clean socket library
  closesocket(sock);
  //delete [] prbuf;
  free((void *)prbuf);
  free((void *)pbuf);
  WSACleanup();
  return 0;
}



地主 发表时间: 01/03 15:45

论坛: 菜鸟乐园

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号