LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 573|回复: 3

请问如何获得router IP

[复制链接]
发表于 2006-4-27 15:47:39 | 显示全部楼层 |阅读模式
请问如何获得router IP

我碰到的问题是这样的
有一台中心服务器(有公网固定IP)
客户端PC(通过路由器+adsl上网)

现在服务器端想获得客户端PC的路由器的IP,
不知道怎么实现?

谢谢
发表于 2006-4-27 16:16:26 | 显示全部楼层
route信息记录在/proc/net/route文件中,你可以像ps一样直接打开这个文件从该文件中读到router的IP
回复 支持 反对

使用道具 举报

发表于 2006-4-27 20:21:59 | 显示全部楼层

从<TCP/IP网络实验篇》上抄的,看看用得上不?


  1. /*
  2. * file: scanroute.c
  3. * date:2006 - 4- 26
  4. */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <unistd.h>
  9. #include <netdb.h>
  10. #include <sys/time.h>
  11. #include <sys/socket.h>
  12. #include <sys/types.h>
  13. #include <netinet/in_systm.h>
  14. #include <netinet/in.h>
  15. #include <netinet/ip.h>
  16. #include <netinet/ip_icmp.h>

  17. #define __FAVOR_BSD

  18. #include <netinet/udp.h>
  19. #include <arpa/inet.h>

  20. enum {CMD_NAME, DST_IP};
  21. enum {ON, OFF};

  22. #define MAXHOSTNAMELEN 256
  23. #define BUFSIZE 512

  24. struct packet_udp
  25. {
  26.         struct ip ip;
  27.         struct udphdr udp;
  28. };

  29. void make_ip_header(struct ip *ip, int src_ip, int dst_ip, int ip_len);
  30. void make_udp_header(struct udphdr *udp);
  31. void tvsub(struct timeval *out, struct timeval *in);
  32. u_short checksum(u_short *data, int len);

  33. int main(int argc, char * argv[])
  34. {
  35.         struct packet_udp sendpacket;        /* UDP packet to be sent */
  36.         struct sockaddr_in send_sa;
  37.         int send_sd;
  38.         int recv_sd;
  39.         int len;
  40.         int ttl;
  41.         int i;
  42.         u_char buff[BUFSIZE];
  43.         struct timeval tvm0;        /* the time packet sent */
  44.         struct timeval tvm1;        /* the time packet received */
  45.         struct timeval tv;                /* (select)'s time out */
  46.         fd_set readfd;                        /* descriptor for (select) check */
  47.         int on = 1;
  48.         int dns_flg = ON;                /* whether to resolve host's domain name */

  49.         /* check arg "-n" */
  50.         if(argc == 3 && (strcmp(argv[1], "-n") == 0))
  51.         {
  52.                 dns_flg = OFF;
  53.                 argv[1] = argv[2];
  54.                 argv[2] = NULL;
  55.                 argc = 2;
  56.         }
  57.         if(argc != 2)
  58.         {
  59.                 fprintf(stderr, "usage: %s [-n] dst_ip \n", argv[CMD_NAME]);
  60.                 exit(EXIT_FAILURE);
  61.         }

  62.         memset((char *)&send_sa, 0, sizeof(struct sockaddr_in));
  63.         send_sa.sin_family = AF_INET;

  64.         /* convert domain name to IP */
  65.         if((send_sa.sin_addr.s_addr = inet_addr(argv[DST_IP])) == INADDR_NONE)
  66.         {
  67.                 struct hostent *he;

  68.                 if((he = gethostbyname(argv[DST_IP])) == NULL)
  69.                 {
  70.                         fprintf(stderr, "unknow host %s \n", argv[DST_IP]);
  71.                         exit(EXIT_FAILURE);
  72.                 }

  73.                 send_sa.sin_family = he->h_addrtype;
  74.                 memcpy((char*)&(send_sa.sin_addr), he->h_addr, sizeof(he->h_length));
  75.         }

  76.         /* open a RAW socket for UDP to send */
  77.         if((send_sd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
  78.         {
  79.                 perror("socket(RAW)");
  80.                 exit(EXIT_FAILURE);
  81.         }

  82.         if(setsockopt(send_sd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0)
  83.         {
  84.                 perror("setsockopt(IPPROTO_IP, IP_HDRINCL)");
  85.                 exit(EXIT_FAILURE);
  86.         }

  87.         /* open a RAW socket for ICMP to receive */
  88.         if((recv_sd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
  89.         {
  90.                 perror("socket(SOCK_RAW)");
  91.                 exit(EXIT_FAILURE);
  92.         }

  93.         /* generate a UDP packet */
  94.         len = sizeof(struct packet_udp);
  95.         memset((char*)&sendpacket, 0, sizeof(struct packet_udp));
  96.         make_udp_header(&(sendpacket.udp));
  97.         make_ip_header(&(sendpacket.ip), 0, send_sa.sin_addr.s_addr, len);

  98.         /* main routine */
  99.         printf("Scanroute %s \n", inet_ntoa(send_sa.sin_addr));
  100.         for(ttl = 1; ttl <= 64; ttl++)
  101.         {
  102.                 printf("%2d: ", ttl);
  103.                 fflush(stdout);

  104.                 sendpacket.ip.ip_ttl = ttl;

  105.                 for(i = 0; i < 3; i++)
  106.                 {
  107.                         /* send a UDP packet */
  108.                         if(sendto(send_sd, (char*)&sendpacket, len, 0,
  109.                                 (struct sockaddr *)&send_sa, sizeof(send_sa)) < 0)
  110.                         {
  111.                                 perror("sendto");
  112.                                 exit(EXIT_FAILURE);
  113.                         }

  114.                         /* store the time sent */
  115.                         gettimeofday(&tvm0, (struct timezone *)0);

  116.                         /* set time out */
  117.                         tv.tv_sec = 3;
  118.                         tv.tv_usec = 0;

  119. reread:
  120.                         /* check descriptors using "select" */
  121.                         FD_ZERO(&readfd);
  122.                         FD_SET(recv_sd, &readfd);

  123.                         if((select(recv_sd+1, &readfd, NULL, NULL, &tv)) > 0)
  124.                         {
  125.                                 int hlen;        /* len of header */
  126.                                 struct icmp *icmp;
  127.                                 struct ip *ip;
  128.                                 struct hostent *host;
  129.                                 char hostip[256];
  130.                                 struct in_addr ipaddr;

  131.                                 /* receive a ICMP packet */
  132.                                 if(recvfrom(recv_sd, buff, BUFSIZE, 0, NULL, NULL) < 0)
  133.                                 {
  134.                                         perror("recvfrom");
  135.                                         exit(EXIT_FAILURE);
  136.                                 }

  137.                                 ip = (struct ip *)buff;
  138.                                 hlen = ip->ip_hl << 2;

  139.                                 if(ip->ip_p != IPPROTO_ICMP)
  140.                                         goto reread;

  141.                                 icmp = (struct icmp *)(buff + hlen);

  142.                                 /* don't receive unrelated packets */
  143.                                 if((icmp->icmp_type != ICMP_TIMXCEED
  144.                                         || icmp->icmp_code != ICMP_TIMXCEED_INTRANS)
  145.                                         && (icmp->icmp_type != ICMP_UNREACH_PORT))
  146.                                         goto reread;

  147.                                 /* store the time received packet */
  148.                                 gettimeofday(&tvm1, (struct timezone *)0);
  149.                                 tvsub(&tvm1, &tvm0);

  150.                                 memcpy(&ipaddr, &(ip->ip_src.s_addr), sizeof(ipaddr));
  151.                                 strcpy(hostip, inet_ntoa(*(struct in_addr *)&(ip->ip_src.s_addr)));

  152.                                 /* display IP and domain name */
  153.                                 if(dns_flg == OFF)
  154.                                         printf("% -15s", hostip);
  155.                                 else if((host= gethostbyaddr((char*)&ipaddr, 4, AF_INET)) == NULL)
  156.                                         printf("%-15s(%S)", hostip, hostip);
  157.                                 else
  158.                                         printf("%-15s(%S)", hostip, host->h_name);

  159.                                 printf(":RTT= %8.4fms", tvm1.tv_sec*1000.0 + tvm1.tv_usec/1000.0);

  160.                                 /* check whether reached dst host */
  161.                                 if(icmp->icmp_type == ICMP_UNREACH_PORT)
  162.                                 {
  163.                                         printf("\n Reach!\n");
  164.                                         goto exit;
  165.                                 }
  166.                                 else
  167.                                         break;
  168.                         }
  169.                         else
  170.                         {
  171.                                 printf("?");
  172.                                 fflush(stdout);
  173.                         }
  174.                 }
  175.                 printf(" \n");
  176.         }
  177. exit:
  178.         close(send_sd);
  179.         close(recv_sd);

  180.         return EXIT_SUCCESS;
  181. }

  182. /*************************************************/





  183. void make_udp_header(struct udphdr *udp)
  184. {
  185.         udp->uh_sport = htons(0);
  186.         udp->uh_ulen = htons((u_short)sizeof(struct udphdr));
  187.         udp->uh_dport = htons(33434);        /* port of traceroute */
  188.         udp->uh_sum = htons(0);
  189. }


  190. void make_ip_header(struct ip *ip, int src_ip, int dst_ip, int ip_len)
  191. {
  192.         memset((char *)ip, 0, sizeof(struct ip));

  193.         /* generate an IP header */
  194.         ip->ip_v = IPVERSION;
  195.         ip->ip_hl = sizeof(struct ip) >> 2;
  196.         ip->ip_id = htons(0);
  197.         ip->ip_off = 0;

  198. #ifdef _linux
  199.         /* linux's RAW IP */
  200.         ip->ip_len = htons(ip_len);
  201.         ip->ip_off = htons(0);
  202. #else
  203.         /* BSD's RAW IP */
  204.         ip->ip_len = ip_len;
  205.         ip->ip_off = 0;
  206. #endif
  207.         ip->ip_ttl = 64;
  208.         ip->ip_p = IPPROTO_UDP;
  209.         ip->ip_src.s_addr = src_ip;
  210.         ip->ip_dst.s_addr = dst_ip;

  211.         /* calc the checksum */
  212.         ip->ip_sum = 0;
  213.         ip->ip_sum = checksum((u_short *)ip, sizeof(struct ip));
  214. }


  215. void tvsub(struct timeval *out, struct timeval * in)
  216. {
  217.         if( (out->tv_usec -= in->tv_usec) < 0)
  218.         {
  219.                 out->tv_sec --;
  220.                 out->tv_usec += 1000000;
  221.         }
  222.         out->tv_sec -= in->tv_sec;
  223. }


  224.        
  225. u_short checksum(u_short *data, int len)
  226. {
  227.         u_long sum = 0;

  228.         /* increase 2 bytes at one time */
  229.         for(; len > 1; len -= 2)
  230.         {
  231.                 sum += *data++;
  232.                 if(sum & 0x80000000)
  233.                         sum = (sum & 0xffff) + (sum >> 16);
  234.         }

  235.         /* process if len is odd */
  236.         if(len == 1)
  237.         {
  238.                 u_short i = 0;
  239.                 *(u_char *)(&i) = * (u_char *)data;
  240.                 sum += i;
  241.         }

  242.         /* process the overflow bit */
  243.         while(sum >> 16)
  244.                 sum = (sum & 0xffff) + (sum >> 16);

  245.         return (sum == 0xffff) ? sum : ~sum;
  246. }                                               
  247.                                        
复制代码
回复 支持 反对

使用道具 举报

发表于 2006-4-28 09:03:05 | 显示全部楼层
Post by Agadoo

  1. /*
  2. * file: scanroute.c
  3. * date:2006 - 4- 26
  4. */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <unistd.h>
  9. #include <netdb.h>
  10. #include <sys/time.h>
  11. #include <sys/socket.h>
  12. #include <sys/types.h>
  13. #include <netinet/in_systm.h>
  14. #include <netinet/in.h>
  15. #include <netinet/ip.h>
  16. #include <netinet/ip_icmp.h>

  17. #define __FAVOR_BSD

  18. #include <netinet/udp.h>
  19. #include <arpa/inet.h>

  20. enum {CMD_NAME, DST_IP};
  21. enum {ON, OFF};

  22. #define MAXHOSTNAMELEN 256
  23. #define BUFSIZE 512

  24. struct packet_udp
  25. {
  26.         struct ip ip;
  27.         struct udphdr udp;
  28. };

  29. void make_ip_header(struct ip *ip, int src_ip, int dst_ip, int ip_len);
  30. void make_udp_header(struct udphdr *udp);
  31. void tvsub(struct timeval *out, struct timeval *in);
  32. u_short checksum(u_short *data, int len);

  33. int main(int argc, char * argv[])
  34. {
  35.         struct packet_udp sendpacket;        /* UDP packet to be sent */
  36.         struct sockaddr_in send_sa;
  37.         int send_sd;
  38.         int recv_sd;
  39.         int len;
  40.         int ttl;
  41.         int i;
  42.         u_char buff[BUFSIZE];
  43.         struct timeval tvm0;        /* the time packet sent */
  44.         struct timeval tvm1;        /* the time packet received */
  45.         struct timeval tv;                /* (select)'s time out */
  46.         fd_set readfd;                        /* descriptor for (select) check */
  47.         int on = 1;
  48.         int dns_flg = ON;                /* whether to resolve host's domain name */

  49.         /* check arg "-n" */
  50.         if(argc == 3 && (strcmp(argv[1], "-n") == 0))
  51.         {
  52.                 dns_flg = OFF;
  53.                 argv[1] = argv[2];
  54.                 argv[2] = NULL;
  55.                 argc = 2;
  56.         }
  57.         if(argc != 2)
  58.         {
  59.                 fprintf(stderr, "usage: %s [-n] dst_ip \n", argv[CMD_NAME]);
  60.                 exit(EXIT_FAILURE);
  61.         }

  62.         memset((char *)&send_sa, 0, sizeof(struct sockaddr_in));
  63.         send_sa.sin_family = AF_INET;

  64.         /* convert domain name to IP */
  65.         if((send_sa.sin_addr.s_addr = inet_addr(argv[DST_IP])) == INADDR_NONE)
  66.         {
  67.                 struct hostent *he;

  68.                 if((he = gethostbyname(argv[DST_IP])) == NULL)
  69.                 {
  70.                         fprintf(stderr, "unknow host %s \n", argv[DST_IP]);
  71.                         exit(EXIT_FAILURE);
  72.                 }

  73.                 send_sa.sin_family = he->h_addrtype;
  74.                 memcpy((char*)&(send_sa.sin_addr), he->h_addr, sizeof(he->h_length));
  75.         }

  76.         /* open a RAW socket for UDP to send */
  77.         if((send_sd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
  78.         {
  79.                 perror("socket(RAW)");
  80.                 exit(EXIT_FAILURE);
  81.         }

  82.         if(setsockopt(send_sd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0)
  83.         {
  84.                 perror("setsockopt(IPPROTO_IP, IP_HDRINCL)");
  85.                 exit(EXIT_FAILURE);
  86.         }

  87.         /* open a RAW socket for ICMP to receive */
  88.         if((recv_sd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
  89.         {
  90.                 perror("socket(SOCK_RAW)");
  91.                 exit(EXIT_FAILURE);
  92.         }

  93.         /* generate a UDP packet */
  94.         len = sizeof(struct packet_udp);
  95.         memset((char*)&sendpacket, 0, sizeof(struct packet_udp));
  96.         make_udp_header(&(sendpacket.udp));
  97.         make_ip_header(&(sendpacket.ip), 0, send_sa.sin_addr.s_addr, len);

  98.         /* main routine */
  99.         printf("Scanroute %s \n", inet_ntoa(send_sa.sin_addr));
  100.         for(ttl = 1; ttl <= 64; ttl++)
  101.         {
  102.                 printf("%2d: ", ttl);
  103.                 fflush(stdout);

  104.                 sendpacket.ip.ip_ttl = ttl;

  105.                 for(i = 0; i < 3; i++)
  106.                 {
  107.                         /* send a UDP packet */
  108.                         if(sendto(send_sd, (char*)&sendpacket, len, 0,
  109.                                 (struct sockaddr *)&send_sa, sizeof(send_sa)) < 0)
  110.                         {
  111.                                 perror("sendto");
  112.                                 exit(EXIT_FAILURE);
  113.                         }

  114.                         /* store the time sent */
  115.                         gettimeofday(&tvm0, (struct timezone *)0);

  116.                         /* set time out */
  117.                         tv.tv_sec = 3;
  118.                         tv.tv_usec = 0;

  119. reread:
  120.                         /* check descriptors using "select" */
  121.                         FD_ZERO(&readfd);
  122.                         FD_SET(recv_sd, &readfd);

  123.                         if((select(recv_sd+1, &readfd, NULL, NULL, &tv)) > 0)
  124.                         {
  125.                                 int hlen;        /* len of header */
  126.                                 struct icmp *icmp;
  127.                                 struct ip *ip;
  128.                                 struct hostent *host;
  129.                                 char hostip[256];
  130.                                 struct in_addr ipaddr;

  131.                                 /* receive a ICMP packet */
  132.                                 if(recvfrom(recv_sd, buff, BUFSIZE, 0, NULL, NULL) < 0)
  133.                                 {
  134.                                         perror("recvfrom");
  135.                                         exit(EXIT_FAILURE);
  136.                                 }

  137.                                 ip = (struct ip *)buff;
  138.                                 hlen = ip->ip_hl << 2;

  139.                                 if(ip->ip_p != IPPROTO_ICMP)
  140.                                         goto reread;

  141.                                 icmp = (struct icmp *)(buff + hlen);

  142.                                 /* don't receive unrelated packets */
  143.                                 if((icmp->icmp_type != ICMP_TIMXCEED
  144.                                         || icmp->icmp_code != ICMP_TIMXCEED_INTRANS)
  145.                                         && (icmp->icmp_type != ICMP_UNREACH_PORT))
  146.                                         goto reread;

  147.                                 /* store the time received packet */
  148.                                 gettimeofday(&tvm1, (struct timezone *)0);
  149.                                 tvsub(&tvm1, &tvm0);

  150.                                 memcpy(&ipaddr, &(ip->ip_src.s_addr), sizeof(ipaddr));
  151.                                 strcpy(hostip, inet_ntoa(*(struct in_addr *)&(ip->ip_src.s_addr)));

  152.                                 /* display IP and domain name */
  153.                                 if(dns_flg == OFF)
  154.                                         printf("% -15s", hostip);
  155.                                 else if((host= gethostbyaddr((char*)&ipaddr, 4, AF_INET)) == NULL)
  156.                                         printf("%-15s(%S)", hostip, hostip);
  157.                                 else
  158.                                         printf("%-15s(%S)", hostip, host->h_name);

  159.                                 printf(":RTT= %8.4fms", tvm1.tv_sec*1000.0 + tvm1.tv_usec/1000.0);

  160.                                 /* check whether reached dst host */
  161.                                 if(icmp->icmp_type == ICMP_UNREACH_PORT)
  162.                                 {
  163.                                         printf("\n Reach!\n");
  164.                                         goto exit;
  165.                                 }
  166.                                 else
  167.                                         break;
  168.                         }
  169.                         else
  170.                         {
  171.                                 printf("?");
  172.                                 fflush(stdout);
  173.                         }
  174.                 }
  175.                 printf(" \n");
  176.         }
  177. exit:
  178.         close(send_sd);
  179.         close(recv_sd);

  180.         return EXIT_SUCCESS;
  181. }

  182. /*************************************************/





  183. void make_udp_header(struct udphdr *udp)
  184. {
  185.         udp->uh_sport = htons(0);
  186.         udp->uh_ulen = htons((u_short)sizeof(struct udphdr));
  187.         udp->uh_dport = htons(33434);        /* port of traceroute */
  188.         udp->uh_sum = htons(0);
  189. }


  190. void make_ip_header(struct ip *ip, int src_ip, int dst_ip, int ip_len)
  191. {
  192.         memset((char *)ip, 0, sizeof(struct ip));

  193.         /* generate an IP header */
  194.         ip->ip_v = IPVERSION;
  195.         ip->ip_hl = sizeof(struct ip) >> 2;
  196.         ip->ip_id = htons(0);
  197.         ip->ip_off = 0;

  198. #ifdef _linux
  199.         /* linux's RAW IP */
  200.         ip->ip_len = htons(ip_len);
  201.         ip->ip_off = htons(0);
  202. #else
  203.         /* BSD's RAW IP */
  204.         ip->ip_len = ip_len;
  205.         ip->ip_off = 0;
  206. #endif
  207.         ip->ip_ttl = 64;
  208.         ip->ip_p = IPPROTO_UDP;
  209.         ip->ip_src.s_addr = src_ip;
  210.         ip->ip_dst.s_addr = dst_ip;

  211.         /* calc the checksum */
  212.         ip->ip_sum = 0;
  213.         ip->ip_sum = checksum((u_short *)ip, sizeof(struct ip));
  214. }


  215. void tvsub(struct timeval *out, struct timeval * in)
  216. {
  217.         if( (out->tv_usec -= in->tv_usec) < 0)
  218.         {
  219.                 out->tv_sec --;
  220.                 out->tv_usec += 1000000;
  221.         }
  222.         out->tv_sec -= in->tv_sec;
  223. }


  224.        
  225. u_short checksum(u_short *data, int len)
  226. {
  227.         u_long sum = 0;

  228.         /* increase 2 bytes at one time */
  229.         for(; len > 1; len -= 2)
  230.         {
  231.                 sum += *data++;
  232.                 if(sum & 0x80000000)
  233.                         sum = (sum & 0xffff) + (sum >> 16);
  234.         }

  235.         /* process if len is odd */
  236.         if(len == 1)
  237.         {
  238.                 u_short i = 0;
  239.                 *(u_char *)(&i) = * (u_char *)data;
  240.                 sum += i;
  241.         }

  242.         /* process the overflow bit */
  243.         while(sum >> 16)
  244.                 sum = (sum & 0xffff) + (sum >> 16);

  245.         return (sum == 0xffff) ? sum : ~sum;
  246. }                                               
  247.                                        
复制代码

没有看完,但是总体上漂了一眼觉得就是自己来填充数据包的头,我觉得这样是做不到的,因为你的router要通过adsl上网,无论你把数据报的头填成什么样,最终会被NAT修改的.我觉得应该像STUN一样将router的IP用数据的形式告诉服务器.
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表