Unmarshalling ethernet frames and data alignment [closed] - c

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
So I'm trying to unmarshall ethernet frames eth and ip headers. I have a program skeleton that reads input data from file and serves me a struct with the frame data.
I have googled and read other posts on the topic but i'm getting nowhere. For example:
Data Alignment with network programming
http://en.wikipedia.org/wiki/Data_structure_alignment
I not sure what the problem is. Obviously im new to C.
If I just try using memcpy and copy data into my structs of eth and ip headers most of the data comes out nice, but not the ip adresses in my ip struct. I also tried reading from the input struct in 1byte, 2byte and 4byte chunks but it doesn't give me correct data.
Here is an example of input data frame from the input file:
200 0000 0002 0200 0000 0012 0800 4500 0026 17d4 81e7 ff01 0000 0a02 0002 0c0c 0c0c 0000 e802 c04b 0004 3e89 3325 0006 ddef 0809
Here is the header structs im using
struct ethhdr{
char da[6];
char sa[6];
uint16_t pt;
};
typedef struct ethhdr ethhdr;
struct iphdr{
#ifdef WORDS_BIGENDIAN
unsigned int ip_v:4; /* version */
unsigned int ip_hl:4; /* header length */
#else
unsigned int ip_hl:4; /* header length */
unsigned int ip_v:4; /* version */
#endif
uint8_t ip_tos; /* type of service */
uint16_t ip_len; /* total length */
uint16_t ip_id; /* identification */
uint16_t ip_off; /* fragment offset field */
uint8_t ip_ttl; /* time to live */
uint8_t ip_p; /* protocol */
uint16_t ip_sum; /* checksum */
uint32_t ip_src, ip_dst; /* source and dest address */
};
typedef struct iphdr iphdr;
The input data struct that im being served.
struct fe_context{
char *pkt; /* Pointer to packet */
size_t len; /* Length of packet */
void *if_in; /* Incoming interface - handle */
};
typedef struct fe_context fe_context;
Sample code of how I've tied to read the data.
int fe_process(fe_context *c)
{
printf("\n\nPacket received!\n");
printf("memcpy to header structs:\n");
ethhdr * ethh = (ethhdr *) malloc(sizeof(ethhdr));
iphdr * iph = (iphdr *) malloc(sizeof(iphdr));
memcpy(ethh, c->pkt, sizeof(ethhdr));
memcpy(iph, c->pkt+sizeof(ethhdr), sizeof(ethhdr));
printf("MAC SA: %02x:%02x:%02x:%02x:%02x:%02x\n", ethh->sa[0], ethh->sa[1], ethh->sa[2],
ethh->sa[3], ethh->sa[4], ethh->sa[5]);
printf("MAC P: %04x\n", ntohs(ethh->pt));
printf("IP Ver: %x\n", ntohl(iph->ip_v));
printf("IP IHL: %x\n", ntohl(iph->ip_hl));
printf("IP TTL: %i\n", iph->ip_ttl);
printf("IP Checksum: %x\n", ntohl(iph->ip_sum));
printf("IP SRC: %08x\n", ntohl(iph->ip_src));
printf("IP DST: %08x\n", ntohl(iph->ip_dst));
char * cp = c->pkt;
printf("\nPacket read by char:\n");
char data;
int p;
for(p = 0; p < 52; p++) {
data = *cp;
cp++;
printf("%02x", data);
if(p%2==1) {
printf(" ");
}
}
printf("\n\n");
cp = c->pkt;
printf("Packet read by uint16_t:\n");
uint16_t data16;
for(p = 0; p < 52/2; p++) {
data16 = *cp;
cp+=2;
printf("%04x ", ntohs(data16));
}
printf("\n\n");
cp = c->pkt;
printf("Packet read by uint32_t:\n");
uint32_t data32;
for(p = 0; p < 52/4; p++) {
data32 = *cp;
cp+=4;
printf("%08x ", ntohl(data32));
}
printf("\n\n");
return 0;
}
And here is its output with the above test data input.
Packet received!
memcpy to header structs:
MAC SA: 02:00:00:00:00:12
MAC P: 0800
IP Ver: 4000000
IP IHL: 5000000
IP TTL: 255
IP Checksum: 0
IP SRC: 0a020000
IP DST: 00000000 // It looks good up until here. this should be 0c0c0c0c
Packet read by char:
0200 0000 0002 0200 0000 0012 0800 4500 0026 17ffffffd4 ffffff81ffffffe7 ffffffff01 0000 0a02 0002 0c0c 0c0c 0000 ffffffe802 ffffffc04b 0004 3effffff89 3325 0006 ffffffddffffffef 0809
Packet read by uint16_t:
0200 0000 0000 0200 0000 0000 0800 4500 0000 1700 81ff ffff 0000 0a00 0000 0c00 0c00 0000 e8ff c0ff 0000 3e00 3300 0000 ddff 0800
Packet read by uint32_t:
02000000 00000000 00000000 08000000 00000000 81ffffff 00000000 00000000 0c000000 e8ffffff 00000000 33000000 ddffffff
As you can see the data in the structs is fine all the way until the DST IP. Could this be because of padding/data alignment? It would appear, by looking at the char read, that the problem somehow happens in the ip header part of the data? When I read by char, where does these 'f's come from?
I tried checking the c->pkt pointer adress and its even. I'm not even sure if that matters though? Im thinking that it will always be since malloc got that for me. Whats the right way of reading this data for for parsing/unmarshalling? I am going to be doing alterations to this data so I would prefer to get the data into neat structs.
Do I have a simple error in my code or am I going about it the wrong way? Any help is much appreciated!

I noticed you made an error on the line:
memcpy(iph, c->pkt+sizeof(ethhdr), sizeof(ethhdr));
You're copying sizeof(ethhdr) bytes for your IP header instead of sizeof(iphdr) which is what you want here. Seems like you made a typo.

Related

0 is converted to 128

I am trying to do SNMP Set from host Linux to target system. But, instead of correct values, wrong values are getting set. After a bit of research, I made this table:
Hex representation of decimal value in Linux snmp
0 - 0x80 - 1000 0000 - 0 is converted to 128
1 - 0x40 - 0100 0000 - 1 is converted to 64
2 0x20 - 0010 0000 - 2 is converted to 32
3 0x10 - 0001 0000 - 3 is converted to 16
4 0x08 - 0000 1000 - 4 is converted to 8
5 0x04 - 0000 0100 - 5 is converted to 4
6 0x02 - 0000 0010 - 6 is converted to 2
7 0x01 - 0000 0001 - is converted to 1
Hex representation of decimal value in target system
0 - 0x00 - 0000 0000
1 - 0x01 - 0000 0001
2 0x02 - 0000 0010
3 0x03 - 0000 0011
4 0x04 - 0000 0100
5 0x05 - 0000 0101
6 0x06 - 0000 0110
7 0x07 - 0000 0111
I have two questions:
What could be the reason behind this issue?
Does anyone know how I can convert those Linux values to correct target values in a C program?
If I understand your question correctly, you receive a byte that encode 8 values (0 to 7) using a one-hot encoding. See https://en.wikipedia.org/wiki/One-hot (notice: your bit order seems reversed though).
If you simply put a one-hot encoded bit pattern into a byte variable on your target system, you'll not get the original value as your target system uses another encoding (probably 2's complement). In other words - a given bit pattern has different meanings in one-hot encoding and 2's complement encoding.
So the task is to convert the one-hot encoded values to equivalent values on your target system.
You could go for a simple switch-statement - like:
int main(void)
{
unsigned char linux_snmp_value = 0x20;
unsigned char target_value = 255;
switch(linux_snmp_value)
{
case 0x80:
target_value = 0;
break;
case 0x40:
target_value = 1;
break;
case 0x20:
target_value = 2;
break;
// Add the remaining cases here
default:
// Illegal value
// Add some error handling
break;
}
printf("Target value %d\n", target_value);
return 0;
}
If you prefer a loop, it could be something like:
int main(void)
{
unsigned char linux_snmp_value = 0x01;
unsigned char target_value = 0;
unsigned char mask = 0x80;
while (mask)
{
if (mask == linux_snmp_value) break;
++target_value;
mask = mask >> 1;
}
if (mask == 0)
{
// Illegal value
// Add some error handling
printf("ERROR\n");
return -1;
}
printf("Target value %d\n", target_value);
return 0;
}
If the portability is not the issue (for example you do not play to compile on the VAX or AVR8 machine) you can use machine instructions for it
asm (“bsrl %1, %0” : “=r” (position) : “r” (number));
you can also wrap it into nice inline function.
Similar instructions are available on ARM, MIPS, PIC and many other.

TCP Checksum in C [duplicate]

This question already has answers here:
C Programming TCP Checksum
(4 answers)
Closed 5 years ago.
I've been trying to calculate the checksum of a TCP header in C. For my purposes, the TCP header is 20 bytes long and has no extra data or options. Also, according to my knowledge, the TCP checksum is calculated as the one's complement of the one's complement sum of the 16 bit words in the header. So, I wrote a function to calculate the TCP checksum, considering the conditions I stated above. However, when I examine the packet being sent out after I calculate the checksum, I get this:
1 0.000000 10.0.2.15 -> 127.0.0.1 TCP 74 24131->8000 [SYN] Seq=0 Win=13273 [TCP CHECKSUM INCORRECT] Len=20
I examined the packet using tshark. However, I also examined the packets with Wireshark, and it also said the same thing. Except, that in parenthesis, it said, "maybe caused by TCP checksum offload?" Which, I don't fully understand.
Here's the code I used to calculate the checksum:
unsigned short tcp_checksum(struct tcphdr* tcph,struct iphdr* iph) {
/* Calculate TCP checksum */
struct pseudo_hdr* pseudo_hdr;
u_char* buffer;
u_char* segment;
u_char* pseudo_segment;
unsigned int count = 32;
unsigned long sum = 0;
unsigned short mask = 0xffff;
unsigned long long* hdr;
pseudo_hdr = malloc(sizeof(struct pseudo_hdr)); // allocate memory
buffer = malloc(32); // allocate for 32 bytes of information
if (pseudo_hdr == NULL || buffer == NULL) { // if memory wasn't allocated properly
err();
if (pseudo_hdr != NULL) free(pseudo_hdr);
if (buffer != NULL) free(buffer);
return 0;
}
pseudo_hdr->saddr = (unsigned long)iph->saddr; // we add the cast because the fields if of type u_int_32
pseudo_hdr->daddr = (unsigned long)iph->daddr; // same reason for adding the cast as above
bzero(&pseudo_hdr->reserved,sizeof(pseudo_hdr->reserved)); // zero header
pseudo_hdr->proto = IPPROTO_TCP; // this will always be 6
pseudo_hdr->len = htons(tcph->doff*4); // length of tcp header
/* Place both headers into a buffer */
segment = (u_char*)tcph;
pseudo_segment = (u_char*)pseudo_hdr;
/* Concactenate */
memcpy((char*)buffer,(char*)pseudo_segment,sizeof(struct pseudo_hdr)); // first the pseudo header
memcpy((char*)buffer+12,(char*)segment,sizeof(struct tcphdr)); // then the TCP segment
/* Calculate checksum just like IP checksum (RFC C implementation) */
hdr = (unsigned long long*)buffer;
while (count > 1) {
sum += *(unsigned short*)hdr++;
count -= 2;
}
// Add left over bytes, if any
if (count > 0) sum += * (u_char*) hdr;
// Fold 32-bit sum to 16 bits
while (sum>>16) sum = (sum & mask) + (sum >> 16);
sum = ~sum; // bitwise NOT operation
/* Discard headers and buffer */
free(buffer);
free(pseudo_hdr);
return sum;
}
struct iphdr and struct tcphdr are defined in <netinet/ip.h> and <netinet/tcp.h>. Here's my definition of struct pseudo_hdr:
struct pseudo_hdr {
unsigned long saddr; // 4 bytes
unsigned long daddr; // 4 bytes
unsigned char reserved; // 1 byte
unsigned char proto; // 1 byte
unsigned short len; // 2 bytes
};
/* Total = 4+4+1+1+2 = 12 bytes */
As I said, this function, for my purposes, calculates the checksum for a TCP header that is 20 bytes long.
Thank you for any help or recommendations.
#RonMaupin's suggestions about checking out the RFC's and the contribution of everyone else to further my understanding of TCP (and C in general!) helped me to solve my problem. Thank you!

C fwrite() -ing an struct does not match fwrite() -ing the structs items separately

Good morning,
I am trying to write the content of following struct to a file (more specifically a BMP file) and am wondering why the binary outputs of fwriteing the entire struct and fwriteing the items of the struct separately differ. Is this the way C works? :O
typedef struct _BitmapFileHeader_
{
u_int16_t bfType; // ID field - BM is the (Microsoft) standard, value should
// be 0x424D
u_int32_t bfSize; // The size of the BMP file in bytes
u_int32_t bfReserved; // Reserved, should be 0x0
u_int32_t bfOffBits; // Offset of the byte where the image data begins
} BitmapFileHeader;
BitmapFileHeader bfh;
bfh.bfType = 0x4D42;
bfh.bfSize = (54 + 8);
bfh.bfReserved = 0;
bfh.bfOffBits = 54;
After using
fwrite(&bfh, sizeof(BitmapFileHeader), 1, img_handle)
the output of od -x output.bmp is:
4d42 0000 004e 0000 0000 0000 0036 0000
But when I use
fwrite(&bfh.bfType, sizeof(u_int16_t), 1, img_handle);
fwrite(&bfh.bfSize, sizeof(u_int32_t), 1, img_handle);
fwrite(&bfh.bfReserved, sizeof(u_int32_t), 1, img_handle);
fwrite(&bfh.bfOffBits, sizeof(u_int32_t), 1, img_handle);
the output is
4d42 004e 0000 0000 0000 0036 0000
Basically, fwrite seems to convert my u_int16_t to u_int32_t. Is this just regular behaviour of fwrite I should expect anyway, or am I missing some important point?
Cheers,
Compiler adds padding to struct in order to align data in memory for performance. Size of struct will not always be adding size of its all members.
Add #pragma pack (1) at beginning of your file, and see the result. #pragma pack (1) will instruct compiler padding as 1 byte.

image data of bmp in C

How to convert a monochrome bmp image file (in my case 16*16 pixels) into binary format? This code reads the bitmap information. I have to store the pixel information into an array & it's not stored properly. I have shared the code
#pragma pack(push, 1)
typedef struct BitMap
{
short Signature;
long Reserved1;
long Reserved2;
long DataOffSet;
long Size;
long Width;
long Height;
short Planes;
short BitsPerPixel;
long Compression;
long SizeImage;
long XPixelsPreMeter;
long YPixelsPreMeter;
long ColorsUsed;
long ColorsImportant;
long data[16];
}BitMap;
#pragma pack(pop)
reading image file:
struct BitMap source_info;
struct Pix source_pix;
FILE *fp;
FILE *Dfp;
Dfp=fopen("filename.bin","wb")
if(!(fp=fopen("filename.bmp","rb")))
{
printf(" can not open file");
exit(-1);
}
fread(&source_info, sizeof(source_info),1,fp);
printf("%d\n",source_info.DataOffSet);
printf("%d\n",source_info.Width*source_info.Height);
for(i=0;i<16;i++)
fprintf(Dfp,"%d\t",source_info.data[i]);
Observed output using hex editor is
Highlighted data i want to get stored in data array so that i can use it further in the code.
However output in filename.bin is
0 16777215 63 63 63 95 95 95
31 31 31 31 31 31 31 31
I'm new to this field. Can someone help me out where i'm going wrong?
There's actually no problem with the data.
The problem is you're using the wrong way to print them.
Try replacing your code:
printf("%d\n",source_info.DataOffSet);
printf("%d\n",source_info.Width*source_info.Height);
for(i=0;i<16;i++)
fprintf(Dfp,"%d\t",source_info.data[i]);
with this:
printf("%x\n",source_info.DataOffSet);
printf("%x\n",source_info.Width*source_info.Height);
for(i=0;i<16;i++)
fprintf(Dfp,"%x\t",source_info.data[i]);
As %d is for signed decimals while %x is for hexadecimals. See the section of The conversion specifier in the manual page of printf
EDITED:
As you've posted your new questions in the comments:
output in hex is 0x00 0xffffff 0x3f 0x3f 0x3f 0x5f 0x5f 0x5f 0x1f 0x1f 0x1f 0x1f 0x1f 0x1f 0x1f 0x1f Can u explain how the output is getting stored? I'm unable to get the same output – user2967899 7 mins ago
here's my edited answer.
Assumptions: your working platform is just as normal, on which size of short is 2 bytes and of long it's 4.
From definition of struct BitMap we know the field data is at its offset of 0x36. Comparing of the image we know the data shall be (in hexadecimal):
data[0]: 0000 0000
data[1]: ffff ff00
......
Then the result you got seems strange since data[1] is 0x00ffffffff instead of 0xffffff00. However that's correct. This is cause by endianess, for which please read this wiki page first: http://en.wikipedia.org/wiki/Endianness
As the hex-editor represents data in the real order of bytes, and I assume you're working with a little-endian machine (which most PC on this planet has), this order is just reversed of the real order of your data in long:
/* data in C */
unsigned long x = 305419896; /* 305419896 == 0x12345678 */
/* arithmetically the four bytes in x: */
/* 0x12 0x34 0x56 0x78 */
/* the real order to be observed in a hex-editor due to endianess: */
/* 0x78 0x56 0x34 0x12 */
/* so this holds true in C: */
unsigned char *a = &x;
assert(a[0] == 0x78);
assert(a[1] == 0x56);
assert(a[2] == 0x34);
assert(a[3] == 0x12);

raw socket send two packets on a virtual Network

I've a problem with my sendto function in my code, when I try to send a raw ethernet packet.
I use a Ubuntu 12.04.01 LTS, with two tap devices connected over two vde_switches and a dpipe
Example:
my send programm create the packet like below, the programm is binded by the socket from tap0 and send the packet to tap1. On tap1 one receiver wait for all packets on socket.
My raw ethernet packet looks so:
destination Addr ____source Addr _________ type/length ___data
00:00:01:00:00:00___00:00:01:00:00:01____ length in Byte__some data
Example packet to send:
00:00:01:00:00:00 00:00:01:00:00:01 (length in byte) (Message)test
but my programm generate two packets, when I look in wireshark:
first packet is an IPX packet and [Malformed Packet] and looks like in hex (data = test)
00 04 00 01 00 06 00 00 01 00 00 01 00 00 00 01 74 65 73 74 00
Linux cooked capture
Packet type: sent by us (4)
Link-layer address type: 1
Link-layer address length: 6
Source: 00:00:01:00:00:01
Protocol: Raw 802.3 (0x0001)
[Malformed Packet: IPX]
second packet unknown protocol
00 00 00 01 00 06 00 00 01 00 00 01 00 00 31 00 74 65 73 74 00
Linux cooked capture
Packet type: Unicast to us (0)
Link-layer address type: 1
Link-layer address length: 6
Source: 00:00:01:00:00:01
Protocol: Unknown (0x3100)
Data
Data: 7465737400
[Length: 5]
outcut from my source code
sock_desc = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
/*struct for sending*/
sock_addr.sll_family = AF_PACKET;
sock_addr.sll_protocol = htons(ETH_P_802_3);
sock_addr.sll_ifindex = if_nametoindex(argv[1]);
sock_addr.sll_hatype = ARPHRD_ETHER; //Ethernet 10Mbps
sock_addr.sll_pkttype = PACKET_HOST; // Paket zu irgendjemand
sock_addr.sll_halen = ETH_ALEN; //6 Oktets in einer ethernet addr
/*MAC Length 8 Oktets*/
sock_addr.sll_addr[0] = frame.src_mac[0];
sock_addr.sll_addr[1] = frame.src_mac[1];
sock_addr.sll_addr[2] = frame.src_mac[2];
sock_addr.sll_addr[3] = frame.src_mac[3];
sock_addr.sll_addr[4] = frame.src_mac[4];
sock_addr.sll_addr[5] = frame.src_mac[5];
/*not in use*/
sock_addr.sll_addr[6] = 0x00;
sock_addr.sll_addr[7] = 0x00;
memset(buffer, '0', sizeof(char)*ETH_FRAME_LEN);
/*set the frame header*/
/*build RAW Ethernet packet*/
buffer[0] = frame.dest_mac[0];
buffer[1] = frame.dest_mac[1];
buffer[2] = frame.dest_mac[2];
buffer[3] = frame.dest_mac[3];
buffer[4] = frame.dest_mac[4];
buffer[5] = frame.dest_mac[5];
buffer[6] = frame.src_mac[0];
buffer[7] = frame.src_mac[1];
buffer[8] = frame.src_mac[2];
buffer[9] = frame.src_mac[3];
buffer[10] = frame.src_mac[4];
buffer[11] = frame.src_mac[5];
while(frame.data[0] != '*'){
printf("Input: ");
scanf("%s", frame.data);
tempLength = 0;
while(frame.data[tempLength] != '\0'){
tempLength++;
}
input = 0;
for(sendLen = 14;sendLen <= (14+tempLength);sendLen++){
buffer[sendLen] = frame.data[input];
input++;
}
sprintf(convLen,"%x", (14 + input));
buffer[12] = convLen[0];
buffer[13] = convLen[1];
length_in_byte = sendto(sock_desc, buffer, 14+input,0,(struct sockaddr*) &sock_addr,sizeof(struct sockaddr_ll));
if(length_in_byte <= 0){
printf("Error beim Senden");
}else{
printf("\n");
printf("src: %02x:%02x:%02x:%02x:%02x:%02x\t->\tdest: %02x:%02x:%02x:%02x:%02x:%02x\n",frame.src_mac[0],frame.src_mac[1],frame.src_mac[2],frame.src_mac[3],frame.src_mac[4],frame.src_mac[5],frame.dest_mac[0],frame.dest_mac[1],frame.dest_mac[2],frame.dest_mac[3],frame.dest_mac[4],frame.dest_mac[5]);
printf("Data: %s\n", frame.data);
}
}
please i need some help to find my mistake.
Thank you forward.
Please give us the lines dealing with the socket creation operation.
I assume you have created your socket like that :
int socket = socket(AF_PACKET,SOCK_RAW,IPPROTO_IP)
You are right when you build the ethernet header (by the way you should use instead struct ethhdr, it's cleaner).
After that you send your data, without putting L4 header and L3 header.... It's normal that your code doesn't work.
I assume you now the OSI Model.
If it's not the case read the paper before reading the next text.
So when you want to create a RAW packet, you have many things to do before.
For example if you want to use TCP/IP protocol you will have to do the next operation
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#DEFINE SIZEMAX 1000
int main() {
char buffer[65535] // MDU
// CREATE YOUR SOCKET
int socket = socket(AF_PACKET,SOCK_RAW,IPPROTO_RAW) ;
// You can also specify some opt to your socket but I let you done your own stuffs
struct ethhdr * ethdr ;
struct iphdr * iph ;
struct tcphdr * tcph;
// Fill all the fields of these last structures (i can't do it for you too long).
// Fill the buffer
memcpy(buffer,ethdr,sizeof(struct ethhdr)) ;
// Deplace it to the good addr
buffer = buffer + sizeof(struct ethhdr) ;
memcpy(buffer,iph,sizeof(struct iphdr)) ;
buffer = buffer + sizeof(struct iphdr)) ;
memcpy(buffer,tcph,sizeof(struct tcphdr)) ;
printf("your entry : \n") ;
char * entry = malloc(SIZEMAX) ;
sncanf("%s",entry,100) ;
buffer = buffer+ 100 ;
memcpy(buffer,entry,100) ;
int size_send = sendto(socket,.......) ;
if(size_send =< 0)
perror("error sending data") ;
return 0 ;
}
This is pseudo-code but it tell you how to send raw packet.
This paper will do the work for you :
RAW Socket TCP/IP
Hope it will help you
Anthony
I think your code is missing the ethernet "packet type ID field". See struct ethhdr in if_ether.h. Now you put convLen where the proto should be. It probably matches the proto number of IPX. Try setting it to something (eg ETH_P_IP) or test what happens when you set it to zero.
I understand you want to make your own protocol and are using the field after the ethernet addresses for the length. However I do suggest you keep at least the ethernet level header standards compliant and build your own on top of that (in the ethernet frame payload). Otherwise youll get problems with tools(like wireshark) and device drivers that try to parse the ethernet headers.
As to why you send two packets, I think the reason lies in the way you scanf input from the user. The while loop is peculiar. I suggest trying to send some data with a fixed input, eg char msg[] = "Test";
Sorry if the answer is vague. It is difficult to help you, since your code is not complete and I can not test it.
OK I see why my receiver receiv two packets. The first packet ist the send by us packet and the second is the Unicast to us. The problem I don't need the first packet to receive. I have test my code and have one capture with the two packets as example.
First frame in hex code from Wireshark:
0004 0001 0006 0000010000020000 0060 the message
Second frame:
0000 0001 0006 0000010000020000 1234 the message
This is Linux cooked capture an means:
2 Bytes packet typ // 0 = To us; 1 = Broadcast; 2 = Multicast; 3 = from somebody to somebody; 4 = sent by us
2 Bytes LINUX ARPHDR_ value
2 Bytes Link layer addr. lenght
8 Bytes source address
2 Bytes Ethernet protocol //e.g. 1 Novell 802.3 without 802.2 header; 4 frames with 802.2 header
My questions:
First is it possible to filter or ignore the first packet?
Second why contains the first packet the protocol typ from the send structur and the second packet the protocol typ from buffer?
Example:
For the first packet
sock_addr.sll_family = AF_PACKET;
sock_addr.sll_protocol = htons(0x0060);
sock_addr.sll_ifindex = 3;
sock_addr.sll_hatype = ARPHRD_ETHER;
sock_addr.sll_pkttype = PACKET_HOST;
sock_addr.sll_halen = ETH_ALEN;
/*MAC Length 8 Oktets*/
sock_addr.sll_addr[0] = 0x00;
sock_addr.sll_addr[1] = 0x00;
sock_addr.sll_addr[2] = 0x01
sock_addr.sll_addr[3] = 0x00;
sock_addr.sll_addr[4] = 0x00;
sock_addr.sll_addr[5] = 0x02;
/*not in use*/
sock_addr.sll_addr[6] = 0x00;
sock_addr.sll_addr[7] = 0x00;
for second packet the buffer like 802.3 frame
buffer[0-5] = 0x00 0x00 0x01 0x00 0x00 0x03 // Destination address
buffer[6-11] = 0x00 0x00 0x01 0x00 0x00 0x02 // Source address
buffer[12-13] = 0x12 0x34 // Protocol dummy typ
My receiver can capture the first packet without a connection between two vde_switches and when I connect the switches with dpipe and vde_plug can I capture the second packet too.

Resources