QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1819|回复: 1

自己编程查询qq好友ID地址的归属地(ZT)

[复制链接]
发表于 2004-12-19 23:13:28 | 显示全部楼层 |阅读模式
用gaim+libqq插件上QQ时,当你给别人发消息或者人家发消息过来时,能察看对方ip BBS 水木清华站 (Mon Mar 3 18:05:02 2003), 转信
名称:qqip
功能:用gaim+libqq插件上QQ时,当你给别人发消息或者人家发消息过来时,能察看对方ip
和所在地.
使用方法:1.需要ip地址和所在地的数据库,可以直接利用wry.dll这个数据文件.
(很多QQ显ip都是用这个,可以在windows版QQ目录找到)
2.执行qqip /dir/to/wry.dll ,如果wry.dll在 ~/.gaim/下,直接执行qqip
3.如果有gaim在运行,就会显示3分种内有消息交换的好友的ip地址和所在地信
息,按时间排列,即刚发过的消息排在最上面.如果有多个
gaim在运行,会叫你选择一个跟踪.
4.按回车刷新,按Ctrl+D退出.
原理:
读取/proc/net/ip_conntrack的信息加以分析,然后查找数据文件中相关所在地.

例如:
[root@simenking work]# ./qqip
Found running gaim:
1 24914/gaim 0.0.0.0:60542
0 :
Press ENTER to refresh or CTRL+D to exit
0 :
Press ENTER to refresh or CTRL+D to exit
0 :
Press ENTER to refresh or CTRL+D to exit//发了一条消息后.
1 :
179 218.24.72.108:12356 辽宁省 沈阳市
Press ENTER to refresh or CTRL+D to exit
1 :
177 218.24.72.108:12356 辽宁省 沈阳市
Press ENTER to refresh or CTRL+D to exit

源码:
[code:1]
/*file:qqip.c
usage:
qqip <ipdata file>
if there is no ipdata file specified,then $HOME/.gaim/wry.dll will be used.
*/

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

/*#define DEBUG 1*/

#define SIP_LEN 0x10
#define EIP_LEN 0x10
#define tmp_len 0x05
#define COUN_LEN 0x0d
#define LOCA_LEN 0x2f
#define THX_LEN 0x0d
#define RSIZE (0x10 * 7 - 2)
#define WRY_H (0x10 * 12 + 2)

#ifdef DEBUG
#define DEBUGP printf
#else
#define DEBUGP(arg,...) do{}while(0)
#endif

struct wry_t{
char sip[SIP_LEN];
char eip[EIP_LEN];
char _tmp[tmp_len];
char country[COUN_LEN];
char local[LOCA_LEN];
char thank[THX_LEN];
};

struct list_t{
struct wry_t recode;
struct list_t *next;
};

struct list_t *head=NULL;

void *xmalloc(size_t size)
{
void *p;
if((p=(void*)malloc(size))==NULL){
printf("malloc error.\n");
exit(-1);
}
return p;
}

void readdb(char *file)
{
FILE *fdb;
size_t n;
char buf[256];
struct list_t *tail=NULL,*plist=NULL;

if(!(fdb=fopen(file,"r"))){
printf("Open ipdata file %s failed.\n",file);
exit(-1);
}

/*skip wry.dll's head recode*/
if(0!=fseek(fdb,(long)WRY_H,SEEK_SET)){
printf("seek ipdata file error.\n");
fclose(fdb);
exit(-1);
}

while(1){
char *p;
plist=(struct list_t*)malloc(sizeof(struct list_t));

n=fread(&plist->recode,1,sizeof(struct wry_t),fdb);

if(n!=sizeof(struct wry_t)){
free(plist);
break;
}

plist->recode.sip[SIP_LEN-1]='\0';
plist->recode.eip[EIP_LEN-1]='\0';
plist->recode.country[COUN_LEN-1]='\0';
/*strip the last space-chars */
p=&plist->recode.country[COUN_LEN-2];
for(;p>=plist->recode.country && isspace(*p);p--) *p='\0';

plist->recode.local[LOCA_LEN-1]='\0';

p=&plist->recode.local[LOCA_LEN-2];
for(;p>=plist->recode.local && isspace(*p);p--) *p='\0';

plist->recode.thank[THX_LEN-1]='\0';
plist->next=NULL;

if(!head) head=tail=plist;
tail->next=plist;
tail=plist;
}

fclose(fdb);

if(!head){
printf("no recode to read from ipdata file %s.\n",file);
exit(-1);
}
return;
}

#define TOK(i,a,b) \
tok=strtok(a,b); \
if(!tok) goto err; \
ips[i]=atoi(tok); \
if(ips[i]>255) goto err

int ipconv(unsigned long *ip,char *sip)
{
char *tok,*s=NULL;
unsigned char ips[4];

s=strdup(sip);
TOK(0,s,".");
TOK(1,NULL,".");
TOK(2,NULL,".");
TOK(3,NULL,"");

*ip=htonl(*(unsigned long*)&ips);
free(s);
return 0;
err:
if(s) free(s);
return -1;
}

#undef TOK

struct ip2local{
int time;
char ip[16];
char port[8];
};

void lookup(struct ip2local *ipl)
{
struct list_t *p=head,*found=NULL;
long i=0;
unsigned long sip,eip,ip;

if(ipconv(&ip,ipl->ip)==-1)
{
printf("Invalid address [%s].\n",ipl->ip);
return;
}
for(;p;p=p->next){
if(ipconv(&sip,p->recode.sip)==-1
||ipconv(&eip,p->recode.eip)==-1) continue;

if(sip>ip||ip>eip) continue;

found=p;
i++;
if(i>20) break;
}

if(found){
printf("%3d %s:%s %s\t%s\n",ipl->time,ipl->ip,ipl->port,
/* found->recode.sip,
found->recode.eip,*/
found->recode.country,
found->recode.local);
}
return;
}

int compar(const void *a,const void *b)
{
return ((struct ip2local*)b)->time - ((struct ip2local*)a)->time;
}


int main(int argc,char **argv)
{

FILE *pexec=NULL;
char cmdbuf[2048],dbfile[256];
char port[8][8],*pport,*tok;
int i=0;
size_t n;

if(argc>2||(argc==2&&0==strcmp(argv[1],"-h"))){
printf("Usage: %s [options] <ipdata file>\n"
"Options:\n\t-h\tprint this message.\n",
(tok=strrchr(argv[0],'/'))?tok+1:argv[0]);
exit(-1);
}

if(argc==2)
strncpy(dbfile,argv[1],sizeof(dbfile));
else
snprintf(dbfile,sizeof(dbfile),"%s/%s",getenv("HOME"),".gaim/wry.dll");


snprintf(cmdbuf,sizeof(cmdbuf),"netstat -nulp|grep gaim|awk '{print $6,$4}'");
pexec=popen(cmdbuf,"r");
n=fread(cmdbuf,1,sizeof(cmdbuf),pexec);
cmdbuf[n]='\0';
pclose(pexec);

tok=strtok(cmdbuf,"\n");
if(tok){
printf("Found running gaim:\n");
while(tok){
char *pptr;
if((pptr=strstr(tok,":"))&&i<8){
printf("%2d\t%s\n",++i,tok);
strncpy(port[i-1],pptr+1,8);
}
tok=strtok(NULL,"\n");
}
}
else{
printf("No running gaim found.\n");
exit(-1);
}

readdb(dbfile);

pport=port[0];
if(i>1){
int j=0;
while(j<1||j>i){
char buf[125],*p;
printf("Please select a gaim to track[1-%d]:",i);
scanf("%s",buf);
for(p=buf;*p&&isdigit(*p);p++);
if(*p) continue;
sscanf(buf,"%d",&j);
}
pport=port[j-1];
}

while(1){
char buf[125],*tok,*seg=NULL;
struct ip2local *p;
int i,rn;

snprintf(cmdbuf,sizeof(cmdbuf),"cat /proc/net/ip_conntrack"
"|grep -v \"dport=8000\""
"|grep udp|grep \"sport=%s\"",pport);
pexec=popen(cmdbuf,"r");
n=fread(cmdbuf,1,sizeof(cmdbuf),pexec);
cmdbuf[n]='\0';
pclose(pexec);

/*
sprintf(cmdbuf,"udp 17 123 src=10.111.20.132 dst=218.72.125.45 sport=%s dport=1024 \n"
"udp 17 14 src=210.32.190.26 dst=10.111.20.132 sport=5632 dport=%s src=10.111.20.132 "
"dst=210.32.190.26 sport=%s dport=5632 [] used=1\n",pport,pport,pport);

*/

for(tok=cmdbuf,i=0;*tok;tok++)
if(*tok=='\n') i++;
if((rn=i))
p=(struct ip2local *)xmalloc(sizeof(struct ip2local)*i);
else
p=NULL;
seg=cmdbuf;
sprintf(buf,"sport=%s",pport);

DEBUGP("%d :\n%s",rn,cmdbuf);

printf("%d :\n",rn);

for(;i;i--){
/*locate the sig*/
tok=strstr(seg,buf);
/*get the dport*/
*strchr(strstr(tok,"dport="),' ')='\0';
strncpy(p[i-1].port,strstr(tok,"dport=")+6,sizeof(p[i-1].port));
/*get the dst ip*/
tok-=25;
*strchr(strstr(tok,"dst="),' ')='\0';
strncpy(p[i-1].ip,strstr(tok,"dst=")+4,sizeof(p[i-1].ip));
/*get the lefttime*/
if(sscanf(strstr(seg,"17")+3,"%d",&p[i-1].time)!=1) p[i-i].time=0;

if(i>1) /*get ready for next parse*/
while(*seg++!='\n');
}

qsort(p,rn,sizeof(struct ip2local),compar);

for(i=0;i<rn;i++){
lookup(&p[i]);
}
if(p)
free(p);
printf("Press ENTER to refresh or CTRL+D to exit");
if(fgets(buf,sizeof(buf),stdin)==NULL) break;

}

puts("");

exit(0);

}

[/code:1]
发表于 2004-12-21 01:42:15 | 显示全部楼层
帮顶
回复

使用道具 举报

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

本版积分规则

GMT+8, 2024-11-6 21:32 , Processed in 0.047603 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

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