我想提出一个C方案,其中一台膝上型计算机(分析服务器)作为另一个膝上型计算机(MeLAN用户可上网)的HTTP转发器,两种手提电脑通过局域网相互连接。
我实施的步骤是:
1) (in the child process)listen at eth1 and if destination port == 80 , then modify packet - (a) write destination ip and source port in router.txt (b) change source IP, source and destination mac addr, checksum (c) inject the modified packet in wlan1 interface using pcap_inject.
2) (in the parent process)listen to wlan1 and if source ip & destination port number exist in router.txt & source port == 80,then modify packet - (a) change destination ip, source and destination mac addr, checksum. (b) inject the modified packet in eth0 interface using pcap_inject.
www.un.org/Depts/DGACM/index_spanish.htm 在分析交通<>时提出的问题——包装单由轮驱动器成功发送,但I dont从目的地IP(第74.125.236.52(google.com)得到任何答复。
主要原因可能是,我没有适当建造包装箱(但我已经彻底检查了每批细节(特别是检查),或者也许在头盔中需要改变一些细节。 我不知道我为什么不从服务器中收回答复。
PS——1)请告诉我,如果我犯过一些非常基本的错误(如我的做法是错误的,或者这种方法永远不能用来发送包裹)。
2) 我总是能够联系到用户手提电脑的互联网。 制定这一方案的总体目的是学习如何推进工作。
#include <stdio.h>
#include <pcap.h>
#include <pcap/pcap.h>
#include <stdlib.h>
#include <netinet/if_ether.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <ctype.h>
#include <netdb.h>
#include <ifaddrs.h>
typedef struct router_table_struct
{ uint8_t port;
char ip[16];
}router_table_struct;
int counter=0;
#define ETHERNET_HEADER_LEN 14
#define WIRELESS_INTERFACE "wlan1" //////////
#define ETHERNET_INTERFACE "eth0"
#define ETHER_ADDRESS_PATH_WIRELESS "/sys/class/net/wlan1/address" /////
#define ETHER_ADDRESS_PATH_LAN "/sys/class/net/eth0/address"
#define ROUTER_TABLE_PATH "/home/---/router_table.txt"
#define ETHER_ADDRESS_ROUTER "**"
#define ETHER_ADDRESS_PRAGYA_LAN "**"
#define IP_PRAGYA_LAN "****"
u_char* modify_packet(u_char *pkt_ptr, pcap_t *eth_handle, pcap_t *wlan_handle, int pkt_type, int len);
int change_ether_addr_dest(uint8_t pkt_type, struct ether_header *eth_hdr);
int change_ether_addr_source(uint8_t pkt_type, struct ether_header *eth_hdr);
int change_ip_addr(struct ip *ip_hdr, uint8_t pkt_type);
uint16_t ip_checksum(struct ip *ip_hdr);
int* parse_ip_address(char *);
uint8_t *parse_ether_address(char *ether_addr_str);
int check_if_packet_exists(char *ipaddr, uint16_t port);
int add_entry_in_router_table(char *ipaddr, uint16_t port);
int show_packet_contents(u_char *pkt_ptr, int len);
int main()
{
struct pcap_pkthdr header;
u_char *pkt_ptr;
pcap_t *wlan_handle, *eth_handle;
char errbuf[PCAP_ERRBUF_SIZE];
char *source_ip, *dest_ip;
uint8_t dest_port, source_port;
eth_handle = pcap_open_live(ETHERNET_INTERFACE,65535,0, 0, errbuf);//////
wlan_handle = pcap_open_live(WIRELESS_INTERFACE,65535,0, 0,errbuf); /////
if (eth_handle == NULL)
{ printf("Couldn t open ethernet handle: %s
",errbuf); return(2); }
if (wlan_handle == NULL)
{ printf("Couldn t open wlan_handle: %s
",errbuf); return(2); }
int c;
pid_t pid = fork();
if(pid == 0) /*** for reading packets from local LAN, forwarding them to wireless router and saving them ********/
{ c = 0;
while(c < 50)
{ pkt_ptr = (u_char *)pcap_next(eth_handle,&header); ////////
struct ether_header *eth_hdr = (struct ether_header *)pkt_ptr;
struct ip *ip_hdr = (struct ip *)(pkt_ptr + 14);
struct tcphdr *tcp_hdr = (struct tcphdr *)(pkt_ptr + 14 + 20);
printf("local LAN count: %d: %s.%hu %d",c, inet_ntoa(ip_hdr->ip_src), ntohs(tcp_hdr->source),ntohs(ip_hdr->ip_len));
printf(" : %s.%hu version: %d
", inet_ntoa(ip_hdr->ip_dst), ntohs(tcp_hdr->dest), ip_hdr->ip_v);
dest_port = ntohs(tcp_hdr->dest);
source_ip = inet_ntoa(ip_hdr->ip_src);
if(!strcmp(source_ip, IP_PRAGYA_LAN) && dest_port == 80) ///////
{
u_char *ptr = modify_packet(pkt_ptr, eth_handle, wlan_handle, (uint8_t)1, header.len);
int packets_injected = pcap_inject(wlan_handle,(const u_char *)ptr, header.len); ///////////
printf("
injected: %d
",packets_injected);
if(packets_injected == -1) { printf("error: %s
",pcap_geterr(wlan_handle)); }
}
c++;
}
}
else /****** for reading packets from wireless router, checking if they need to be forwarded and forwarding them to local LAN*******/
{ c = 0;
while(c < 150)
{ pkt_ptr = (u_char *)pcap_next(wlan_handle,&header); ///////
struct ether_header *eth_hdr = (struct ether_header *)pkt_ptr;
struct ip *ip_hdr = (struct ip *)(pkt_ptr + 14);
struct tcphdr *tcp_hdr = (struct tcphdr *)(pkt_ptr + 14 + 20);
printf("Wireless count: %d: %s.%u %d",c, inet_ntoa(ip_hdr->ip_src), ntohs(tcp_hdr->source),ntohs(ip_hdr->ip_len));
printf(" : %s.%u version: %d
", inet_ntoa(ip_hdr->ip_dst), ntohs(tcp_hdr->dest), ip_hdr->ip_v);
char *ip_source=inet_ntoa(ip_hdr->ip_src);
dest_port = ntohs(tcp_hdr->dest);
if(check_if_packet_exists(ip_source, dest_port) && ntohs(tcp_hdr->source) == 80 && ntohs(eth_hdr->ether_type) == 0x0800)
{
u_char *ptr = modify_packet(pkt_ptr, eth_handle, wlan_handle, (uint8_t)0, header.len);
int packets_injected = pcap_inject(eth_handle,(const void *)ptr, header.len); ////
printf("
injected: %d
",packets_injected);
if(packets_injected == -1){ printf("error: %s
",pcap_geterr(eth_handle)); }
}
c++;
}
waitpid(pid, NULL, 0);
pcap_close(eth_handle);
pcap_close(wlan_handle);
}
}
uint16_t ip_checksum (struct ip *ip_hdr)
{ int *ipsrc_parse = parse_ip_address(inet_ntoa(ip_hdr->ip_src));
int *ipdst_parse = parse_ip_address(inet_ntoa(ip_hdr->ip_dst));
int sum = (((unsigned int)ip_hdr->ip_v<<12 | (unsigned int)ip_hdr->ip_hl<<8 | (ip_hdr->ip_tos)) +
(ntohs(ip_hdr->ip_len))+
(ntohs(ip_hdr->ip_id))+
(ntohs(ip_hdr->ip_off))+
((ip_hdr->ip_ttl)<<8 | (ip_hdr->ip_p))+
(ipsrc_parse[0]<<8 | ipsrc_parse[1])+
(ipsrc_parse[2]<<8 | ipsrc_parse[3])+
(ipdst_parse[0]<<8 | ipdst_parse[1])+
(ipdst_parse[2]<<8 | ipdst_parse[3]));
int chk_sum = ((sum & 0x0000ffff) + ((sum & 0xffff0000)>>16));
return (uint16_t)(~chk_sum);
}
u_char *modify_packet(u_char *pkt_ptr, pcap_t *eth_handle, pcap_t *wlan_handle, int pkt_type, int len)
{ //printf("inside modify packet
");
printf("contents of the pakcet without modification:
");
show_packet_contents(pkt_ptr, len);
struct ether_header *eth_hdr = (struct ether_header *)pkt_ptr;
struct ip *ip_hdr = (struct ip *)(pkt_ptr + ETHERNET_HEADER_LEN); //point to an IP header structure
int header_len = (int)(ip_hdr->ip_hl*4);
struct tcphdr *tcp_hdr = (struct tcphdr *)(pkt_ptr + ETHERNET_HEADER_LEN + header_len);
if(pkt_type == 0)
{ inet_aton(IP_PRAGYA_LAN, &ip_hdr->ip_dst);
}
else
{ if(!check_if_packet_exists(inet_ntoa(ip_hdr->ip_dst),(uint16_t)( ntohs(tcp_hdr->source)) ))
add_entry_in_router_table(inet_ntoa(ip_hdr->ip_dst),(uint16_t)ntohs(tcp_hdr->source) );
change_ip_addr(ip_hdr, pkt_type);
}
change_ether_addr_source(pkt_type, eth_hdr);
change_ether_addr_dest(pkt_type, eth_hdr);
ip_hdr->ip_sum = (htons)(ip_checksum(ip_hdr));
printf("end of modify packet
");
return pkt_ptr;
}
int* parse_ip_address(char *ipaddr)
{ //printf("parse ip address
");
int i=-1, num = 0, p = 1,j=0;
int *ipaddr_parse = malloc(sizeof(int)*4);
char ch;
do
{ i++;
ch = ipaddr[i];
if(ch == . || ch == )
{ ipaddr_parse[j] = num;
p = 1;
num = 0;
j++;
}
else
{ num = num*p + (ch-48);
if (p == 1) p = 10;
}
} while(ipaddr[i]!= );
//printf("
%d %d %d %d
",ipaddr_parse[0], ipaddr_parse[1], ipaddr_parse[2], ipaddr_parse[3]);
return ipaddr_parse;
}
uint8_t *parse_ether_address(char *ether_addr_str)
{ //printf("parse ether address
");
int i =-1,c,j=0;
char ch;
uint8_t num=0, *ether_addr = malloc(sizeof(int)*6);
do
{ i++;
ch = ether_addr_str[i];
if(ch == : || ch == )
{ ether_addr[j] = num;
num = 0;
j++;
}
else
{ c = (ch>57)? ch-87 : ch-48;
num = num*16 + c;
}
} while(ether_addr_str[i] != );
printf("MAC- ");
for(i=0;i<6;i++)
printf("%x:",ether_addr[i]);
printf("
");
return ether_addr;
}
int add_entry_in_router_table(char *ipaddr, uint16_t port)
{ //printf("add entry in router table
");
FILE *rtable_fp = fopen(ROUTER_TABLE_PATH,"a+");
router_table_struct rtable_ptr;
while((fscanf(rtable_fp, "%s %hhu", rtable_ptr.ip, &rtable_ptr.port )) !=EOF);
fprintf(rtable_fp,"%s %hu
", ipaddr, port);
fclose(rtable_fp);
}
int check_if_packet_exists(char *ipaddr, uint16_t port)
{ //printf("check if packet exists
");
FILE *rtable_fp = fopen(ROUTER_TABLE_PATH,"a+");
router_table_struct rtable_ptr;
while((fscanf(rtable_fp, "%s %hhu", rtable_ptr.ip, &rtable_ptr.port )) !=EOF) //to check if ip address is already mapped
{
if(!strcmp(ipaddr,rtable_ptr.ip) && port == rtable_ptr.port)
{ fclose(rtable_fp);
return 1;
}
}
fclose(rtable_fp);
return 0;
}
int change_ip_addr(struct ip *ip_hdr, uint8_t pkt_type)
{ //printf("inside change ip address
");
struct ifaddrs *ifap;
getifaddrs(&ifap);
char host[NI_MAXHOST], *errbuf;
char *iface = WIRELESS_INTERFACE;
while(ifap != NULL)
{ if(ifap->ifa_addr->sa_family == AF_INET && !strcmp(iface,ifap->ifa_name) )
{ getnameinfo(ifap->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
printf("address: %s %s
", host,ifap->ifa_name);
break;
}
ifap = ifap->ifa_next;
}gin processing the packets in this particular file, one at a time
inet_aton(host, &ip_hdr->ip_src);
}
int change_ether_addr_source(uint8_t pkt_type, struct ether_header *eth_hdr)
{ //printf("change_ether_addr_source
");
FILE *fp_ether;
if(pkt_type == 0)
fp_ether = fopen(ETHER_ADDRESS_PATH_LAN, "r");
else
fp_ether = fopen(ETHER_ADDRESS_PATH_WIRELESS, "r");
char *ether_src = malloc(17);
fscanf(fp_ether, "%s", ether_src);
printf("%s
",ether_src);
fclose(fp_ether);
uint8_t *ether_source = parse_ether_address(ether_src);
int i;
for(i=0;i<6;i++)
eth_hdr->ether_shost[i] = ether_source[i];
}
int change_ether_addr_dest(uint8_t pkt_type, struct ether_header *eth_hdr)
{ //printf("inside change ether address dest
");
uint8_t *ether_dest;
if(pkt_type == 0)
ether_dest = parse_ether_address(ETHER_ADDRESS_PRAGYA_LAN);
else
ether_dest = parse_ether_address(ETHER_ADDRESS_ROUTER);
int i;
for(i=0;i<6;i++)
eth_hdr->ether_dhost[i] = ether_dest[i];
}
int show_packet_contents(u_char *pkt_ptr, int len)
{
struct ether_header *eth_hdr = (struct ether_header *)pkt_ptr;
struct ip *ip_hdr = (struct ip *)(pkt_ptr + ETHERNET_HEADER_LEN); //point to an IP header structure
int header_len = (int)(ip_hdr->ip_hl*4);
struct tcphdr *tcp_hdr = (struct tcphdr *)(pkt_ptr + ETHERNET_HEADER_LEN + header_len);
int j=0;
printf("Packet length: %d
",len);
printf("ethernet source: ");
int i;
for(i=0;i<6;i++)
printf("%x:",eth_hdr->ether_shost[i]);
printf("
");
printf("ethernet dest: ");
for(i=0;i<6;i++)
printf("%x:",eth_hdr->ether_dhost[i]);
printf("
ethernet type: %x
",ntohs(eth_hdr->ether_type));
printf("
");
printf("IP PACKET CONTENTS
");
printf("IP version : %x
",(unsigned int)ip_hdr->ip_v);
printf("IP Header length: %x
",(unsigned int)ip_hdr->ip_hl);
printf("IP tos : %x
",(uint8_t)(ip_hdr->ip_tos));
printf("IP Packet length: %x
",(uint16_t)ntohs(ip_hdr->ip_len));
printf("IP Id : %x
",(uint16_t)ntohs(ip_hdr->ip_id));
printf("IP offset : %x
",(uint16_t)ntohs(ip_hdr->ip_off));
printf("IP TTL : %x
",(uint8_t)(ip_hdr->ip_ttl));
printf("IP protocol : %x
",(uint8_t)(ip_hdr->ip_p));
printf("IP checksum : %x
",(uint16_t)ntohs(ip_hdr->ip_sum));
printf("IP src_addr : %s
",inet_ntoa(ip_hdr->ip_src));
printf("IP dst_addr : %s
",inet_ntoa(ip_hdr->ip_dst));
printf("TCP_PACKET_CONTENTS
");
printf("source port: %hu
",(uint16_t)ntohs(tcp_hdr->source));
printf("destination port: %hu
",(uint16_t)ntohs(tcp_hdr->dest));
}
似乎像现在我从服务器那里得到回复一样(Webeshark显示),但网页仍然没有装上。 有时错误是: “与74.125.236.52的联系中断了”,有时是“.......72.218.3.115花了太长的时间来回答”。
服务器的回复包括tcphandhake Packets(syn, syn-ack, ack)和1项“http://www.cp.gov.org”。
(162.254.3.1 是客户手提电脑的IP地址,125.252.226.160(一些随机地点))
3 0.00037016.254.3.1 125.252.226.160 TCP 51442 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460
5 0.063316 125.252.226.160 16.254.3.1 TCP http > 51442 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1460
6 0.063568 162.254.3.1 125.252.226.160 TCP 51442 > http://ACK] Seq=1 Ack=1 Win=5840 Len=0
吉布提
8 0.064114 125.252.226.16016254.3.1 TCP http > 51443 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1460
9 0.064381 162.254.3.1 125.252.226.160 TCP 51443 > http [ACK] Seq=1 Ack=1 Win=5840 Len=0
是否有任何人建议我应如何避免这些错误(连接时间过长),看上下页是否被装?