Home > Mobile >  [C][Mac OS X] gcc : Linker Command Failed with exit code 1
[C][Mac OS X] gcc : Linker Command Failed with exit code 1

Time:10-20

I'm trying to compile this sniffer_mid_16.c. A week ago, I was able to compile this program with just gcc -o sniffer_mid_16 sniffer_mid_16.c. But today, I can't compile this.

The code is:

#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <pcap.h>
#include <arpa/inet.h>
#include <stdlib.h>

struct ether_addr{
    unsigned char ether_addr_octet[6];
};

struct ether_header{
    struct ether_addr ether_dhost;
    struct ether_addr ether_shost;
    unsigned short ether_type;
};

struct pseudo_header{
    unsigned int source_address;
    unsigned int dest_address;
    unsigned char placeholder;
    unsigned char protocol;
    unsigned short tcp_length;
};

struct ip_hdr{
    unsigned char ip_header_len:4;
    unsigned char ip_version:4;
    unsigned char ip_tos;
    unsigned short ip_total_length;
    unsigned short ip_id;
    unsigned char ip_frag_offset:5;
    unsigned char ip_more_fragment:1;
    unsigned char ip_dont_fragment:1;
    unsigned char ip_reserved_zero:1;
    unsigned char ip_frag_offset1;
    unsigned char ip_ttl;
    unsigned char ip_protocol;
    unsigned short ip_checksum;
    unsigned int ip_srcaddr;
    unsigned int ip_destaddr;
};
struct tcp_hdr{
   unsigned short source_port;
   unsigned short dest_port;
   unsigned int sequence;
   unsigned int acknowledge;
   unsigned char ns:1;
   unsigned char reserved_part1:3;
   unsigned char data_offset:4;
   unsigned char fin:1;
   unsigned char syn:1;
   unsigned char rst:1;
   unsigned char psh:1;
   unsigned char ack:1;
   unsigned char urg:1;
   unsigned char ecn:1;
   unsigned char cwr:1;
   unsigned short window;
   unsigned short checksum;
   unsigned short urgent_pointer;
};

void print_raw_packet(const unsigned char* pkt_data, bpf_u_int32 caplen){
    printf("New packet of size : %d\n\t", caplen);
    for(int i=0;i<caplen;i  ){
        printf("%.2x%s%s", pkt_data[i], (i%2==0 ? "" : " "), ((i 1)==0 ? "\n\t" : ""));
    }
    printf("\n");
    return;
}

void print_ether_header(const unsigned char *pkt_data){
    struct ether_header *value = (struct ether_header *) pkt_data;
    printf("Print Ethernet Header : \n");
    printf("\tDestination address: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
            value -> ether_dhost.ether_addr_octet[0],
            value -> ether_dhost.ether_addr_octet[1],
            value -> ether_dhost.ether_addr_octet[2],
            value -> ether_dhost.ether_addr_octet[3],
            value -> ether_dhost.ether_addr_octet[4],
            value -> ether_dhost.ether_addr_octet[5]
            );
    
    printf("\tSource address: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
            value -> ether_shost.ether_addr_octet[0],
            value -> ether_shost.ether_addr_octet[1],
            value -> ether_shost.ether_addr_octet[2],
            value -> ether_shost.ether_addr_octet[3],
            value -> ether_shost.ether_addr_octet[4],
            value -> ether_shost.ether_addr_octet[5]
            );

    printf("ether type : %.4x\n\n", ntohs(value->ether_type));
}

void print_ip_header(const unsigned char* pkt_data){
    struct ip_hdr *value = (struct ip_hdr *)(pkt_data 14);
    printf("Print IP Header : \n\t");
    printf("ip_header_len : %d bytes\n\t", value->ip_header_len * 4);
    printf("ip_version : %d\n\t", value->ip_version);
    printf("type of service : %d\n\t", value->ip_tos);
    printf("packet total length : %d\n\t", ntohs(value->ip_total_length));
    printf("identifier : %.4x\n\t", ntohs(value->ip_id));
    printf("fragment offset field : %d\n\t", (unsigned)value->ip_frag_offset);
    printf("more fragment : %d\n\t", (unsigned int)value->ip_more_fragment);
    printf("don't fragment : %d\n\t", (unsigned int)value->ip_dont_fragment);
    printf("reserved zero : %d\n\t", (unsigned int)value->ip_reserved_zero);
    printf("fragment offset : %d\n\t", (unsigned int)value->ip_frag_offset1);
    printf("time to live : %d\n\t", (unsigned int)value->ip_ttl);
    printf("protocol id : %d\n\t", (unsigned int)value->ip_protocol);
    printf("header checksum : %d\n\t", ntohs(value->ip_checksum));
    printf("source ip address : %s\n\t", inet_ntoa(*(struct in_addr *)&value->ip_srcaddr));
    printf("destination ip address : %s\n\n", inet_ntoa(*(struct in_addr *)&value->ip_destaddr));
}

unsigned int print_tcp_header(const unsigned char* pkt_data){
    struct tcp_hdr *value = (struct tcp_hdr *) (pkt_data  34);
    printf("Print TCP Header : \n\t");
    printf("Source port : %u\n\t", ntohs(value -> source_port));
    printf("Destination port : %u\n\t", ntohs(value->dest_port));
    printf("Sequence : %u\n\t", ntohl(value->sequence));
    printf("Acknowledge : %u\n\t", ntohl(value->acknowledge));
    printf("Nonce sum : %d\n\t", (unsigned int)value->ns);
    printf("Reserved part1 : %d\n\t", (unsigned int)value->reserved_part1);
    printf("Data offset :  %d bytes\n\t", (unsigned int)value->data_offset * 4); 
            //tcp_header size without data (includes options)
    printf("FIN flag : %d\n\t", (unsigned int) value->fin);
    printf("SYN flag : %d\n\t", (unsigned int) value->syn);
    printf("RST flag : %d\n\t", (unsigned int) value->rst);
    printf("PSH flag : %d\n\t", (unsigned int) value->psh);
    printf("ACK flag : %d\n\t", (unsigned int) value->ack);
    printf("URG flag : %d\n\t", (unsigned int) value->urg);
    printf("ECN flag : %d\n\t", (unsigned int) value->ecn);
    printf("CWR flag : %d\n\t", (unsigned int) value->cwr);
    printf("Window size : %d\n\t", ntohs(value->window));
    printf("Checksum : %d\n\t", ntohs(value->checksum));
    printf("Urgent pointer : %d\n", value->urgent_pointer);

    return ((unsigned int)value->data_offset*4);
}

void print_data(const unsigned char* pkt_data, unsigned int tcp_header_without_data, bpf_u_int32 caplen){
    int packet_size_without_data = tcp_header_without_data   34;
    unsigned char* data = (unsigned char *)(pkt_data packet_size_without_data);
    printf("Print Data  : \n\t");
    for(int i=0;i<caplen-packet_size_without_data;i  ){
        printf("%.2x", (int)data[i]);
        if(i%2==1) printf(" ");
   } 
   printf("\n");
}

void detect_attack(const unsigned char* pkt_data, unsigned int tcp_header_without_data, bpf_u_int32 caplen){
    bool attacking = false;
    printf("Is there attack? : ");
    int packet_size_without_data = tcp_header_without_data   34;
    unsigned char* data = (unsigned char *)(pkt_data packet_size_without_data);
    if(caplen - packet_size_without_data < 6){
        printf("no\n\n");
        return;
    }
    for(int i=0;i<caplen-packet_size_without_data-5;i  ){
        if(data[i]=='a' 
        && data[i 1]=='t'
        && data[i 2]=='t'
        && data[i 3]=='a'
        && data[i 4]=='c'
        && data[i 5]=='k'){
            attacking = true;
        }
    }
    if(attacking) printf("yes\n\n");
    else printf("no\n\n");
}

unsigned short in_checksum(unsigned short *ptr, int nbytes){
    register long sum;
    unsigned short oddbyte;
    register short answer;

    sum = 0;
    while(nbytes>1){
        sum =*ptr  ;
        nbytes-=2;
    }
    if(nbytes==1){
        oddbyte=0;
        *((u_char*)&oddbyte) = *(u_char*)ptr;
        sum =oddbyte;
    }
    sum = (sum>>16)   (sum & 0xffff);
    sum = sum   (sum>>16);
    answer = (short)~sum;

    return answer;
}


int main(){
    pcap_if_t *alldevs=NULL;
    char errbuf[PCAP_ERRBUF_SIZE];

    // find all network adapters
    if (pcap_findalldevs(&alldevs, errbuf)==-1){
        printf("dev find failed\n");
        return -1;
    }
    if (alldevs==NULL){
        printf("no devs found\n");
        return -1;
    }
    // print them
    pcap_if_t *d; int i;
    for(d=alldevs,i=0; d!=NULL; d=d->next){
        printf("%d-th dev: %s ",   i, d->name);
        if (d->description)
            printf(" (%s)\n", d->description);
        else
            printf(" (No description available)\n");
    }

    // opening an adapter

    int inum;
    printf("enter the interface number: ");
    scanf("%d", &inum);
    for(d=alldevs, i=0; i<inum-1; d=d->next, i  );

    //open
    pcap_t *fp;
    if((fp=pcap_open_live(d->name, //name of the device
            65536, //capture size
            1, // promiscuous mode
            20, //read timeout
            errbuf
            ))==NULL){
        printf("pcap open failed\n");
        pcap_freealldevs(alldevs);
        return -1;
            }
    printf("pcap open successful\n");

    // Set filtering rules for the traffic : pcap_compile(), pcap_setfilter()
    char filt[35] = "host ***.***.***.***"; //hide IP for ask
    struct bpf_program fcode;
    if(pcap_compile(fp, // pcap handle
            &fcode, // compiled rule
            // (char *)("host ***.***.***.*** and port 16700"), //filter rule, hide IP for ask
            filt,
            1, //optimize
            NULL) < 0){
        printf("pcap compile failed\n");
        pcap_freealldevs(alldevs);
        return -1;
    }

    if(pcap_setfilter(fp, &fcode) < 0){
        printf("pcap setfilter failed\n");
        pcap_freealldevs(alldevs);
        return -1;
    }
    pcap_freealldevs(alldevs);
    

    struct pcap_pkthdr *header;
    const unsigned char *pkt_data;

    int res;
    int cnt=0;
    unsigned int tcp_header_without_data;
    while((res=pcap_next_ex(fp, &header, &pkt_data))>=0){ // 1 if success
        if (res == 0) continue; // 0 if time-out
        printf("%dth packet : \n", cnt  );
        print_raw_packet(pkt_data, header->caplen);
        print_ether_header(pkt_data);
        print_ip_header(pkt_data);
        tcp_header_without_data = print_tcp_header(pkt_data);
        print_data(pkt_data, tcp_header_without_data, header->caplen);
        detect_attack(pkt_data, tcp_header_without_data, header->caplen);
        break;
    }
    printf("=================================\nLet's Send\n");
    const unsigned char* packet = pkt_data; //copy them into another buffer : pkt_data => packet
    struct ip_hdr *ip_value = (struct ip_hdr *)(packet 14);
    struct tcp_hdr *tcp_value = (struct tcp_hdr *)(packet 34);
    int k;
    for(;;){
        printf("which port to check?\n");
        scanf("%d", &k);
        if(k==-1) break;
        tcp_value -> dest_port = ntohs(k);

        ip_value->ip_checksum = 0; // set ip_check_sum to zero
        tcp_value->checksum = 0; // set tcp_check_sumto zero
        ip_value->ip_checksum = in_checksum((unsigned short*)ip_value,20); // recompute ip_check_sum
    
        struct pseudo_header psh;
        inet_pton(AF_INET, "***.***.***.***", &(psh.source_address));
        inet_pton(AF_INET, "***.***.***.***", &(psh.dest_address));
        psh.placeholder = 0;
        psh.protocol = 6;
        psh.tcp_length = htons(tcp_header_without_data);

        // Now build pseudo header   tcp header
        unsigned char *seudo = (unsigned char *)malloc(sizeof(struct pseudo_header)   tcp_header_without_data);
        memcpy(seudo, &psh, sizeof(struct pseudo_header));
        memcpy(seudo   sizeof(struct pseudo_header), tcp_value, tcp_header_without_data);

        //Compute the checksum
        tcp_value->checksum = in_checksum((unsigned short *)seudo,sizeof(struct pseudo_header) tcp_header_without_data); // recompute tcp_check_sum
        
        // send packet to every port
        pcap_sendpacket(fp, packet, 34 tcp_header_without_data);

        //now receive port and analyze it.
        const unsigned char* receive_packet;
        pcap_next_ex(fp, &header, &receive_packet);
        struct ip_hdr *ip_h = (struct ip_hdr*)(receive_packet 14);
        struct tcp_hdr *tcp_h = (struct tcp_hdr*)(receive_packet 34);

        if(tcp_h->syn == 1 && tcp_h -> ack == 1){
            printf("it is a live port\n");
            continue;
            // printf("dest port : %d, src port : %d\n", ntohs(tcp_h -> dest_port), ntohs(tcp_h -> source_port));
        }
        printf("it is a closed port\n");

    }
    return 0;
}

And the error is:

sniffer_mid_16.c:254:13: warning: incompatible pointer to integer conversion passing 'void *' to parameter of type 'bpf_u_int32' (aka 'unsigned int') [-Wint-conversion]
            NULL) < 0){
            ^~~~
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types/_null.h:30:15: note: expanded from macro 'NULL'
#define NULL  __DARWIN_NULL
              ^~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/_types.h:52:23: note: expanded from macro '__DARWIN_NULL'
#define __DARWIN_NULL ((void *)0)
                      ^~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include/pcap.h:466:17: note: passing argument to parameter here
            bpf_u_int32);
                       ^
1 warning generated.

Undefined symbols for architecture arm64:
  "_pcap_compile", referenced from:
      _main in sniffer_mid_16-f7c493.o
  "_pcap_findalldevs", referenced from:
      _main in sniffer_mid_16-f7c493.o
  "_pcap_freealldevs", referenced from:
      _main in sniffer_mid_16-f7c493.o
  "_pcap_next_ex", referenced from:
      _main in sniffer_mid_16-f7c493.o
  "_pcap_open_live", referenced from:
      _main in sniffer_mid_16-f7c493.o
  "_pcap_sendpacket", referenced from:
      _main in sniffer_mid_16-f7c493.o
  "_pcap_setfilter", referenced from:
      _main in sniffer_mid_16-f7c493.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

enter image description here

I tried all things that i could. what should i do?

P.S. I can find pcap. h in "/Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/usr/include/pcap.h" when I clicked "Go to Definition" in vs code.

CodePudding user response:

sniffer_mid_16.c:254:13: warning: incompatible pointer to integer conversion passing 'void *' to parameter of type 'bpf_u_int32' (aka 'unsigned int') [-Wint-conversion]
            NULL) < 0){

That's a call to pcap_compile(); the last argument to pcap_compile() is a 32-bit integrated network mask value, not a pointer. Just pass PCAP_NETMASK_UNKNOWN (that won't work with older versions of libpcap, but reasonably recent versions of various UN*Xes have it).

A week ago, I was able to compile this program with just gcc -o sniffer_mid_16 sniffer_mid_16.c. But today, I can't compile this.

...

Undefined symbols for architecture arm64:
  "_pcap_compile", referenced from:

...

If you were able to compile your program with just gcc -o sniffer_mid_16 sniffer_mid_16.c, you mustn't have put any pcap calls into it yet; if you call routines in libpcap, then, to compile the program on any UN*X (including macOS), you need to compile with -lpcap:

gcc -o sniffer_mid_16 sniffer_mid_16.c -lpcap

The pcap routines are in libpcap, and you must tell the linker to link with that library, otherwise, the linker won't look at that library and won't find those routines.

  • Related