I am attempting to find the MAC address using pcap for a small project. As of right now the structure I am working with looks like this:
struct ethernet_header
{
u_char dhost[6];
u_char shost[6];
u_short type;
};
The call int the code simply loosk like:
void get_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{
const struct ethernet_header *ethernet;
const struct ip_header *ip;
ethernet = (struct ethernet_header *)(packet);
ip = (struct ip_header *)(packet + 16);
printf("Destination MAC: %s\n", ethernet->dhost);
}
The error I am receiveing is
error: dereferencing pointer to incomplete type
Now as far as I know the packet var is being initalized properly because it is being used in other sections of the code without a problem. In the case of the ip struct, this also works fine with no errors. I know what is being loaded into that particluar address I just can't figure out whats going on. Anyone have any ideas.
error: dereferencing pointer to incomplete type
You missed including the header file which defines struct ethernet_header in the c file which has the function void get_packet().
The error is because the compiler cannot see the definition of the structure, most likely you are just forward declaring it. However, Since you dereference the pointer to structure the compiler must know the layout of the structure and hence must see the definition of the structure.
So just include it You need to include the header file which contains the definition of the structure in this particular c file.
These 2 lines are vulnerable to this type of error. Compiler is unable to typecast the data in any or both statements. typecast it with correct datatype, it will work.
ethernet = (struct ethernet_header *)(packet);
ip = (struct ip_header *)(packet + 16);
Related
So, I have to do library sending IPv4 packets (without libraries with prepared headers) and problem is that I can't access field in struct inside struct while using function, though eclipse does not see error, hint does not show that is possible.
Structs:
struct packet{
struct ipv4hdr * iphdr;
struct icmphdr * icmphdr;
char * data;
};
struct ipv4hdr{
u_int8_t version_length;
u_int8_t type;
u_int16_t total_length;
u_int16_t id;
u_int16_t frag_off;
u_int8_t ttl;
u_int8_t protocol;
u_int16_t checksum;
u_int32_t source;
u_int32_t destination;
};
Pointers to function (that is requirement, both work):
struct packet *(*packetCreate)() = dlsym(lib, "createPacket");
void (*setIP)(struct packet *, u_int8_t, u_int8_t, u_int16_t, char*, u_int8_t, char*) = dlsym(lib, "prepareIP");
Creation of struct packet:
struct packet * createPacket(){
struct packet * pack= malloc(sizeof(struct packet));
return pack;
}
Now, calling fields inside main does show posssible fields:
struct packet * pack = packetCreate();
pack->iphdr->(CTRL+space displays all the fields) //and eclipse automatically corrects all the . to ->
Meanwhile calling created pointer on function does not display fields while using hint and that causes segmentation fault (core dumped):
void prepareIP(struct packet * packet, u_int8_t length, u_int8_t type, u_int16_t id, char* destination, u_int8_t ttl, char *data){
packet->iphdr->type = type; //it is not treated by error, though any field causes crash
//meanwhile hint
packet->iphdr->(CTRL+space gets)ipv4hdr;
}
Question again is why I can't call specific field inside function that points to the original struct and how to do this inside that function
It looks like you forgot to allocate space for struct ipv4hdr * iphdr;.
But maybe this isn't even what you intended. Do you really want iphdr to be a pointer in your struct? It makes mucht more sense, if it was part of the struct, like this:
struct packet{
struct ipv4hdr iphdr; // notice that we do not use pointers here!
struct icmphdr icmphdr; // this looks curious to me - we have either an IP or an ICMP package, why both headers in the same package?
char * data;
};
I am getting the following error through the coverity tool -
overrun-buffer-arg: Overrunning struct type in_addr of 4 bytes by passing it to a function which accesses it at byte offset 7 using argument "8UL".
sample code:
static u_long addr;
static struct sockaddr_in remote_server;
addr = inet_addr(remote_servername);
memcpy((char *) &remote_server.sin_addr, (char *)&addr, sizeof(addr));
In the last line, I am getting the above error.
Can someone through some light on, what's going wrong.
Please let me know, if you need any more information.
inet_addr() returns an in_addr_t, not an u_long.
struct sockaddr_in's sin_addr is a struct in_addr, which holds an in_addr_t s_addr.
This should do the trick:
static struct sockaddr_in remote_server;
remote_server.sin_addr.s_addr = inet_addr(remote_servername);
Standard warning: Do not cast a pointer to/from void *.
For the message: read it carefully, it very well states the problem. Just a hint: Use proper types. You are apparently accessing a struct beyond its size. Which size doe u_long have actually?
addr should be serialized properly to an uint8_t[], respecting endianess. As you take sizeof() from the second argument, apparently the first argument is shorter.
Why do you not just assign, but use memcpy()? Check both have the same type.
I am getting some compilation errors I can't figure out, and although I'm sure they're quite stupid I can't find an answer that helps me much through other channels.
Problem 1: (These are a part of a TCP protocol)
error: ‘TH_SYN’ undeclared (first use in this function)
error: ‘TH_ACK’ undeclared (first use in this function)
tcp.tcph_flags = TH_SYN;
tcp.tcph_flags = TH_ACK;
Problem 2:
error: conversion to non-scalar type requested
const int one = 1;
char buffer[PCKT_LEN];
struct sockaddr_in sin;
struct ipheader ip;
struct tcpheader tcp;
ip = (struct ipheader) buffer; /* ERROR POINTS HERE */
tcp = (struct tcpheader) buffer + ip.iph_ihl *4; /* AND HERE */
Problem 3:
warning: assignment makes integer from pointer without a cast
case 'i': dip = inet_addr(optarg);
dstip = (optarg); /* ERROR POINTS TO THIS LINE */
break;
Now I hope I've copied enough relevant information on the errors for you to be able to help, but if I've left something out let me know. For problem 1, I believe I am missing a header file of some sort but I don't know which. Problem 2 and 3 are pointer issues, but I'm not sure why they aren't correct. Thanks in advance :)
For the first problem, include the header defining TH_SYN and TH_ACK. On my system it's netinet/tcp.h
For the second problem, turn ipheader and tcpheader into pointers
For the third problem I think you need a strtoul but I'm unsure
For problem 1, you need
#include <netinet/tcp.h>
For problem 2, struct ipheader should be struct ipheader * in both your declaration and cast, as well as struct tcpheader should be struct tcpheader *
For problem 3, optarg is a pointer, and needs to be dereferenced, so refer to it as *optarg
struct sniff_ip {
struct in_addr ip_src, ip_dst;
}
function{
const struct sniff_ip *ip;
ip = (struct sniff_ip*)(packet +SIZE_ETHERNET);
}
My goal here is to change the values of ip_src and ip_dst, but I can't figure out the correct syntax to modify src or dst when it is in a struct within a struct. I know to access a member within a struct is normally ip->member or (*ip).member , but this doesn't seem to be working for me here. What are the correct procedure(s) for accessing members in the event they are in a struct within a struct?
Edit: I want to change the ip addresses (values) for both src and dst. When using lines such as
"ip->ip_src="
or
"ip->ip_src.s_addr=" , I get the error that
"assignment of read-only location '*ip'
You simply combine the operator in the correct places:
ip->ip_src.s_addr
struct in_addr other_addr;
ip->ip_src = other_addr;
You problem is:
const struct sniff_ip *ip;
instead of:
struct sniff_ip const *ip = ...;
In your current declaration, you have ip, a pointer to a const data of type struct sniff_ip.
Convert a text host address to a numeric address
int inet_pton( int af, const char * src, void * dst );
I have seen two different usages of this functions as follows:
Example 1:
http://man7.org/tlpi/code/online/book/sockets/i6d_ucase_cl.c.html
struct sockaddr_in6 svaddr;
...
inet_pton(AF_INET6, argv[1], &svaddr.sin6_addr)
Example 2:
http://www.qnx.com/developers/docs/6.4.1/neutrino/lib_ref/i/inet_pton.html
struct in6_addr in6addr;
...
inet_pton(AF_INET6, IN6ADDR, &in6addr))
Which one is correct? If all of them are correct, why each of them store the converted network address into totally different data structure?
It's the same structure: svaddr.sin6_addr is of type struct in6_addr.
netinet/in.h
The header shall define the sockaddr_in6 structure,
which shall include at least the following members:
...
struct in6_addr sin6_addr IPv6 address.
As a mater of fact, anything that has enough size will do, as inet_pton is:
int inet_pton(int af, const char *restrict src, void *restrict dst);
^ anything