English 中文(简体)
通过改变头盔内容(Ether, 网络层)和将pcap_inject in ubuntu(C)方案
原标题:forwarding packets by changing header contents(Ether, network layer) and using pcap_inject in ubuntu(C program)

我想提出一个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

是否有任何人建议我应如何避免这些错误(连接时间过长),看上下页是否被装?

问题回答

如果你不想做某些工作/网络工作: 为什么不提你使用象板一样的垃圾,而是在2层? 该软件的目的是什么?





相关问题
Forwarding HTTP Request with Direct Server Return

I have servers spread across several data centers, each storing different files. I want users to be able to access the files on all servers through a single domain and have the individual servers ...

Forwarding from domain names without using frames

I own a domain name e.g. www.mydomain.com I also own a web server e.g. www.myserver.com After navigating to my web server via www.myserver.com clicking on links to different pages within my servers ...

How can I forward a url to the appropriate page?

How can I forward a url such as: http://www.mysite.com/Join to the appropriate page: http://www.mysite.com/JoinOptions/MemberRegistration.aspx Is there some way to do this? I m using a DNN CMS ...

Htaccess redirect

Does anyone have a simple way of rdirected in .htaccess all pages that were once .asp to now be .php. For example index.asp is now index.php etc. Server is apache.

nginx not forwarding POST to @fallback

我在C++上写出了一个高性能的吉大港山区活动服务器,我希望使其与 n和PHP-FPM(fastcgi)毫无关系地工作。 这是我原产地组合的幻灯。

Powershell event forwarding

Sorry for bad english. I have some troubles with powershell and events forwarding mechanism in it. Im trying to do something like this: $remoteComputer = "." $session = New-PsSession $remoteComputer ...

https 301 errors and SEO

This question is related to a few tools that are returning errors and that I am not sure what to do about them, if anything. At: http://andylangton.co.uk/online-tools/http-status-analyser if I ...

热门标签