Raw Ethernet PF_PACKET issue on localhost - raw-ethernet

I am working on raw ethernet programming in c. I have two files client and server which are running on localhost. I am using my own protocol number for communication in socket().
On the client side i have follwing code
s = socket(PF_PACKET, SOCK_RAW, 61187);
unsigned char dest_mac[6]= {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
struct sockaddr_ll socket_address;
socket_address.sll_family = PF_PACKET;
socket_address.sll_protocol = 61187;
socket_address.sll_ifindex = ifindex;
socket_address.sll_hatype = ARPHRD_ETHER;
socket_address.sll_pkttype = PACKET_BROADCAST;
socket_address.sll_halen = ETH_ALEN;
socket_address.sll_addr[0] = dest_mac[0];
socket_address.sll_addr[1] = dest_mac[1];
socket_address.sll_addr[2] = dest_mac[2];
socket_address.sll_addr[3] = dest_mac[3];
socket_address.sll_addr[4] = dest_mac[4];
socket_address.sll_addr[5] = dest_mac[5];
socket_address.sll_addr[6] = 0x00;
socket_address.sll_addr[7] = 0x00;
and then i send some data as follows
sent = sendto(s, buffer, ETH_HEADER_LEN, 0, (struct sockaddr*)&socket_address, sizeof(socket_address));
On the server side i do socket creation as in client and i am doing recvfrom as follows
length = recvfrom(s, buffer, BUF_SIZE, 0, NULL, NULL);
But i dont receive any packet on server side. Could anyone let me know what the problem is?

It's hard to tell from your incomplete example, but I would suspect that you're using a SOCK_RAW where you want to use a SOCK_DGRAM. In your SOCK_RAW, the Ethernet header is assumed to be part of the buffer you specify, i.e. your setting of a destination address is irrelevant to the contents of the packet. With SOCK_DGRAM, the contents of buffer form the payload of the generated Ethernet frame and the header comes from your address field.
This kind of thing is fairly easy to debug when you let tcpdump -neX (or something equivalent with Wireshark or tshark) run while testing - you'll see exactly what packet you are generating.

Related

STM32F415 Problems with I2C

I am using a STM32F415RGT6 embedded in the 1Bitsy Board. I want to set up the I2C Peripheral in order to read some data from a sensor. I am using the stm32f4 standard peripheral library.
My example code:
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitTypeDef gpioInit;
GPIO_StructInit(&gpioInit);
gpioInit.GPIO_Mode = GPIO_Mode_AF;
gpioInit.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
gpioInit.GPIO_PuPd = GPIO_PuPd_UP;
gpioInit.GPIO_Speed = GPIO_Speed_25MHz;
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);
GPIO_Init(GPIOB, &gpioInit);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
I2C_DeInit(I2C1);
I2C_InitTypeDef I2C_InitStructure;
I2C_StructInit(&I2C_InitStructure);
/* I2C configuration */
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_ClockSpeed = 100000;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x01;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
/* Generate Start, send the address and wait for ACK */
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, 0xE0, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
After that I want to write a 0x00, but the code always hangs in the last line, apparently the Master never reads the acknowledge. The I2C status registers always read:
I2C1 -> SR1 = 1024
I2C1 -> SR2 = 3
which means that the Acknowledge Failure bit is always set. If I analyze it using my Saleae I get the following:
The Slave sends the ACK, but the STM32F415 cannot read it.
The weird thing: If I try the same code on my F407 - Disco (only with clock set to 400khz, but it's the same behaviour on both MCUs regardless of Speed), it works flawlessly:
All other peripherals work fine. I already tried several workarounds, but the AF bit is always set, regardless of method. I hope you can help me.
P.S: I have tried with and without additional pullups and the I2C Slave Address is fine, because it works with STM32F0, STM32F4-DISCO and Atmel Mcus.
Best Regards and Thanks in advance!

Microchip XC16 : Can we access Port using its address ?? for ex : &PortA?

As my question says, to access Port by its address, Can we write it as "&PORTA" ??
In my problem, I want to read/write port value from/to HMI, using Modbus Protocol.
I have an array of structure :
typedef struct func_code_reg {
volatile uint16_t addr;
volatile uint16_t *data;
}RW_REG_DATA;
// described as
RW_REG_DATA rwCoilStatusTbl[] = {
// Addr Data_Register
{ 0, &rwCoil_0000 },
{ 1, &rwCoil_0001 },
};
Whenever HMI reads data , it reads the current value of register &rwCoil_000x
Whenever HMI writes data, the register &rwCoil_000x gets updated.
Instead, I would like to use &PORTA to read Port status or to update Port Status.
Is it possible ?? & if possible, is it the correct way to update the Port status ??
Or any better way, please guide me.
(I am using dsPic33E series)
PORTx is already mapped to the contents of the PORTx register, you don't need its address. To read from a port, use the PORTx register. To write, use the LATx register.
So if you want the value rwCoil_000x to be reflected on a port (A), simply write:
LATA = rwCoil_000x;
And if you want to read from the port into the same variable, write:
rwCoil_000x = PORTA;
Of course, this assumes PORTA is set to be a general purpose output.
If you want to generalize over many different ports, you can build an array of volatile references to *PORT.
I did this once for the other way, the outputs, LAT registers, see Using an array of LATs to toggle outputs. type of (byte) pointer to lat

Should we frame whole packet ( headers , check sum, etc ) to use netmap?

I red about netmap which allows user programmers to access packets in the user space, that means user applications can read / send network packets very quickly using this netamp.
netmap :
http://info.iet.unipi.it/~luigi/netmap/
Can any one who are very familiar with netamp, tell me should we create entire packet that we want to send out, or we using the stack features to send it out.
Edit : here is example on how to use this api
https://www.freebsd.org/cgi/man.cgi?query=netmap&sektion=4
#include <net/netmap_user.h>
void sender(void)
{
struct netmap_if *nifp;
struct netmap_ring *ring;
struct nmreq nmr;
struct pollfd fds;
fd = open("/dev/netmap", O_RDWR);
bzero(&nmr, sizeof(nmr));
strcpy(nmr.nr_name, "ix0");
nmr.nm_version = NETMAP_API;
ioctl(fd, NIOCREGIF, &nmr);
p = mmap(0, nmr.nr_memsize, fd);
nifp = NETMAP_IF(p, nmr.nr_offset);
ring = NETMAP_TXRING(nifp, 0);
fds.fd = fd;
fds.events = POLLOUT;
for (;;) {
poll(&fds, 1, -1);
while (!nm_ring_empty(ring)) {
i = ring->cur;
buf = NETMAP_BUF(ring, ring->slot[i].buf_index);
// here they are saying to construct the packet
... prepare packet in buf ...
ring->slot[i].len = ... packet length ...
ring->head = ring->cur = nm_ring_next(ring, i);
}
}
}
You need to create entire packed, including ethernet, ip and tcp headers. Netmap completely bypasses kernel network stack, so you need to do all work yourself.

Reading Data From UDP socket

I use the following function to read from a file descriptor...
int cread(int fd, char *buf, int n){
int nread;
if((nread=read(fd, buf, n))<0){
perror("Reading data");
exit(1);
}
return nread;
}
Following is the function that uses the above function
if(FD_ISSET(tap_fd, &rd_set)){
/* data from tun/tap: just read it and write it to the network */
nread = cread(tap_fd, buffer, BUFSIZE);
tap2net++;
do_debug("TAP2NET %lu: Read %d bytes from the tap interface\n", tap2net, nread);
/* write length + packet */
plength = htons(nread);
nwrite = cwrite(net_fd, (char *)&plength, sizeof(plength));
nwrite = cwrite(net_fd, buffer, nread);
do_debug("TAP2NET %lu: Written %d bytes to the network\n", tap2net, nwrite);
}
They both work fine with TCP siocket but not with udp socket.. Any help would be appreciated
It's not clear exactly what your problem is, but if net_fd is a UDP socket, then the two cwrite() calls will create two UDP datagrams.
There isn't a great deal of point in prepending the size with UDP - UDP maintains the message boundaries for you. So in the UDP case, just remove the plength part entirely.

TCP Connection Seems to Receive Incomplete Data

I've setup a simple TCP file transfer. Everything appears to work OK, except for the received file size is sporadically a smaller size than the file that was sent. There doesn't appear to be any pattern to the size of the received file.
(in the code below, note that the typical client/server rolls are reversed)
My client code is like:
#define kMaxBacklog (5)
// fill out the sockadd_in for the server
struct sockaddr_in servAdddress;
//memcpy() to fill in the sockaddr
//setup the socket
int sockd, returnStatus;
sockd = socket(AF_INET, SOCK_STREAM, 0);
if (sockd == -1)
NSLog(#"could not create client socket");
else
NSLog(#"created client socket");
returnStatus = connect(sockd, (struct sockaddr*)&servAdddress, sizeof(servAdddress));
if (returnStatus == -1)
NSLog(#"could not connect to server - errno:%i", errno);
else
NSLog(#"connected to server");
NSData *dataWithHeader = [self getDataToSend];
returnStatus = send(sockd, [dataWithHeader bytes], [dataWithHeader length], 0);
if (returnStatus == -1)
NSLog(#"could not send file to server");
else if( returnStatus < [dataWithHeader length])
NSLog(#"ONLY PARTIAL FILE SENT");
else
NSLog(#"file sent of size: %i", returnStatus);
shutdown(sockd, SHUT_WR);
close(sockd);
The client method ALWAYS reports that it sent the entire file.
For the server:
#define MAXBUF (10000)
int _socket;
_socket = socket(AF_INET, SOCK_STREAM, 0); // set up the socket
struct sockaddr_in addr;
bzero(&addr, sizeof(addr));
addr.sin_len = sizeof(addr);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(0);
int retval = bind(_socket, (struct sockaddr *)&addr, sizeof(addr));
if (retval == -1)
NSLog(#"server could not bind to socket");
else
NSLog(#"server socket bound");
socklen_t len = sizeof(addr);
retval = getsockname(_socket, (struct sockaddr *)&addr, &len);
if (retval == -1)
NSLog(#"server could not get sock name");
else
NSLog(#"server socket name got");
int socket1, socket2, clientAddrLen, returnStatus;
struct sockaddr_in servAdddress, clientAddress;
clientAddrLen = sizeof(servAdddress);
socket1 = _socket;
returnStatus = listen(socket1, kMaxBacklog);
if (returnStatus == -1)
NSLog(#"server could not listen on socket");
else
NSLog(#"server socket listening");
while(1){
FILE *fd;
int i, readCounter;
char file[MAXBUF];
NSLog(#"server blocking on accept()");
socket2 = accept(socket1, (struct sockaddr*)&clientAddress, (socklen_t*)&clientAddrLen);
if (socket2 == -1)
NSLog(#"server could not accpet the connection");
else
NSLog(#"server connection accepted");
i = 0;
readCounter = recv(socket2, file, MAXBUF, 0);
if(!readCounter)
NSLog(#"server connection cancelled, readCount = 0");
else if (readCounter == -1){
NSLog(#"server could not read filename from socket");
close(socket2);
continue;
}
else
NSLog(#"server reading file of size: %i", readCounter);
fd = fopen([myfilePathObject cStringUsingEncoding:NSASCIIStringEncoding], "wb");
if(!fd){
NSLog(#"server could not open the file for creating");
close(socket2);
continue;
}
else
NSLog(#"server file open for creating");
returnStatus = fwrite([myData bytes], 1, [myData length], fd);
if (returnStatus == -1)
NSLog(#"Error writing data to server side file: %i", errno);
else
NSLog(#"file written to disk);
readCounter = 0;
//close (fd);
returnStatus = fclose(fd);
if(returnStatus)
NSLog(#"server error closing file");
So sporadically, the readCounter variable will not contain the same size as the file that was sent, but some times it does.
If it matters the file transfer is occurring between an iPhone and an iPhone simulator, both over WIFI. This happens regardless of if the phone is the server or if the simulator is the server.
If anyone can help me understand why this is occurring I'd appreciate it. I thought the whole purpose of TCP was to avoid this kind of problem.
(to give credit where it's due, for my server and client code I borrowed heavily from the book: The Definitive Guide to Linux Network Programming, by Davis, Turner and Yocom from Apress)
The recv function can receive as little as 1 byte, you may have to call it multiple times to get your entire payload. Because of this, you need to know how much data you're expecting. Although you can signal completion by closing the connection, that's not really a good idea.
Update:
I should also mention that the send function has the same conventions as recv: you have to call it in a loop because you cannot assume that it will send all your data. While it might always work in your development environment, that's the kind of assumption that will bite you later.
Tim Sylvester and gnibbler both have very good answers, but I think the most clear and complete is a combination of the two.
The recv() function return immediately with whatever is the in the buffer. This will be somewhere between 1 byte and MAXBUF. If the buffer is being written to while recv returns, you wont have the entire data that was sent in the buffer yet.
So you need to call recv() multiple times, and concatenate the data, to get everything that was sent.
A convenient way to do this (since we are working in cocoa) is to use NSMutableData like:
NSMutableData *fileData = [[NSMutableData alloc] init]; //Don't forget to release
while ((readCounter = recv(socket2, file, MAXBUF, 0)) > 0){
if (readCounter == -1){
NSLog(#"server could not read filename from socket");
close(socket2);
continue;
}
else{
NSLog(#"server reading file of size: %i", readCounter);
[fileData appendData:[NSData dataWithBytes:file length:readCounter]];
}
bzero(file, MAXBUF);
readCounter = 0;
}
You should probably have some kind of sequence of characters to signal termination of the file transfer, and only when you read those at the end of a block do you break out of your recv loop.
Of course, you will have to find a sequence that won't occur in your files, or that can be easily escaped. If you're working with text files this is pretty easy, but if not you'll have to be clever.
Alternatively, the client could first send the file size (in a separate send call), so the server knows how many bytes to expect in the file transfer.
recv returns right away with whatever is in the buffer (upto MAXBUF). If the buffer is being written to at the same time you might not get all the data
What TCP ensures is that your message will get to the remote peer correctly. As long as it fits in the send buffer, it will be automatically split into smaller chunks and sent by the local peer, and reordered and reassembled by the remote peer. It is not uncommon for a route to dynamically change while you are sending a message, which you would have to reorder manually (the smaller chunks) before delivering to your application.
As for your actual data transfer, your application needs to agree on a custom protocol. For instance, if you are only sending one message (the file), the sender could signal the receiver that it does not intend to write anymore to the socket (with shutdown(sock, SHUT_WR)), this way recv() returns with 0 and you know the transfer is complete (this is how a HTTP/1.0 server signals the client the transfer is complete). If you intend to send more data, then this alternative is not appropriate.
Another way would be to let the receiver know how much data the sender is going to transmit by including a header, for instance. It does not need to be overly elaborate, you could simply reserve the first 8 bytes to send the length as a 64-bit unsigned integer. In this case, you still need to be careful about byte ordering (big-endian / little-endian).
There is a very useful tutorial on network programming for UNIX environments:
Beej's Guide to Network Programming
You could refer to it to get a quick start, then refer back to the book for completeness, if you need. Even though you did not ask for additional references, TCP/IP Illustrated Vol. 1 and UNIX Network Programming Vol. 1 (both by W. Richard Stevens, the latter with a recent third edition) are excellent references.

Resources