I am trying to communicate between two laptop machines using Wifi. The structure of the radiotap header and ieee80211 header I am using is:
struct ieee80211_radiotap_header {
unsigned char it_version;
uint16_t it_len;
uint32_t it_present;
};
/* Structure for 80211 header */
struct ieee80211_hdr_3addr {
uint16_t frame_ctl[2];
uint16_t duration_id;
unsigned char addr1[ETH_ALEN];
unsigned char addr2[ETH_ALEN];
unsigned char addr3[ETH_ALEN];
uint16_t seq_ctl;
};
struct packet {
struct ieee80211_radiotap_header rtap_header;
struct ieee80211_hdr_3addr iee802_header;
unsigned char payload[30];
};
/* In main program */
struct packet mypacket;
struct ieee80211_radiotap_header ratap_header;
struct ieee80211_hdr_3addr iee802_header;
unsigned char addr1[ETH_ALEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; /* broadcast address */
unsigned char addr2[ETH_ALEN] = {0x28,0xcf,0xda,0xde,0xd3,0xcc}; /* mac address of
network card */
unsigned char addr3[ETH_ALEN] = {0xd8,0xc7,0xc8,0xd7,0x9f,0x21}; /* mac address of
access point i am trying to connect to */
/* Radio tap header data */
ratap_header.it_version = 0x00;
ratap_header.it_len = 0x07;
ratap_header.it_present = (1 << IEEE80211_RADIOTAP_RATE);
mypacket.rtap_header = ratap_header;
/* ieee80211 header data */
iee802_header.frame_ctl[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
IEEE80211_FC0_SUBTYPE_BEACON;
iee802_header.frame_ctl[1] =IEEE80211_FC1_DIR_NODS;
strcpy(iee802_header.addr1,addr1);
strcpy(iee802_header.addr2,addr2);
strcpy(iee802_header.addr3,addr3);
iee802_header.seq_ctl = 0x1086;
mypacket.iee802_header=iee802_header;
/* Payload */
unsigned char payload[PACKET_LENGTH]="temp";
strcpy(mypacket.payload , payload);
I am able to receive the packets when I test the transmission and reception on the same laptop. However I am not able to receive the packet transmitted on a different laptop. Wireshark does not show the packet as well.
Can anyone point out the mistake I am making?
Related
I'm completely new to netlink & co. and I am trying to establisch a connection from user space to the w1-kernel module of a raspberry pi.
Unfortunately the documentation i found is spotty and contradictory.
Here some of the things not clear to me:
basic communication is:
generate a socket: socket()
int s = socket(AF_NETLINK,SOCK_DGRAM, NETLINK_CONNECTOR);
bind it to a local name: bind()
int b = bind(s,(sockaddr*)&sa,sizeof(sa));
with
sa.nl_family=AF_NETLINK;
sa.nl_pid=getpid();//0?
sa.nl_groups=0; //23? -1?
create the message
send it: send()? sendmsg()?
wait for answer: poll()
read answer: recv()
+In examples i found (w1d.c and ucon.c) they use the send() command (not sendmsg) without a connect(), even though the man pages of send say that wouldnt work.
+I am not clear about the structure of the message:
send can send any buffer (char*)
netlink expects a struct nlmsghdr header;
connector expects a struct cn_msg header.
w1_netlink expects a w1_netlink_msg header and w1_netlink_cmd data.
Do i need all headers in a row? Ther are 2 sequence / message number variables, one in nlmsghdr and on in cn_msg???
The test program i wrote is not producing the result i expect: every thing works withour producing an error but i am getting no answer :-(
#include <iostream>
#include <linux/netlink.h>
#include <sys/types.h>
#include <sys/socket.h>
#include<sys/poll.h>
#include <unistd.h>
#include<cstring>
#include "w1_netlink.h"
__u32 nl_seq;
static int netlink_send(int s, struct cn_msg *msg) //copy from (ucon.c)
{
struct nlmsghdr *nlh;
unsigned int size;
int err;
char buf[128];
struct cn_msg *m;
size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len);
nlh = (struct nlmsghdr *)buf;
nlh->nlmsg_seq = nl_seq++;
nlh->nlmsg_pid = getpid();
nlh->nlmsg_type = NLMSG_DONE;
nlh->nlmsg_len = size;
nlh->nlmsg_flags = 0;
m = (cn_msg*) NLMSG_DATA(nlh);
memcpy(m, msg, sizeof(*m) + msg->len);
err = send(s, nlh, size, 0);
return err;
}
int main(int argc, char *argv[])
{
nl_seq=0;
int s = socket(AF_NETLINK,SOCK_DGRAM, NETLINK_CONNECTOR);
if(s==-1) {std::cout<<"no socket"; return s;};
std::cout<<"socket "<<s;
sockaddr_nl sa;
sa.nl_family=AF_NETLINK;
sa.nl_pid=0;//getpid();
sa.nl_groups=0;
int b = bind(s,(sockaddr*)&sa,sizeof(sa));
if(b==-1){std::cout<<"bind error";return b;}; //prints 3
std::cout<<"bind "<<b; //prints 0
int si=sizeof(struct cn_msg)+sizeof(struct w1_netlink_msg)+sizeof(w1_netlink_cmd);
char * buf;
buf=(char *)malloc(1024);
memset(buf,0,1024);
cn_msg *cnh = (cn_msg*)buf;
w1_netlink_msg* wnh=(w1_netlink_msg*)&cnh->data;
w1_netlink_cmd* wcmd = (w1_netlink_cmd*)&wnh->data;
cnh->id.idx=CN_W1_IDX;
cnh->id.val=CN_W1_VAL;
cnh->seq=nl_seq;
cnh->flags=0;
wnh->type=W1_LIST_MASTERS;
wnh->len=0;
cnh->len=sizeof(struct w1_netlink_msg)+sizeof(w1_netlink_cmd);
int len=netlink_send(s,cnh);
std::cout<<"send "<<len<<" "<<(int)wnh->status; //prints 52 0
pollfd pfd;
pfd.fd=s;
pfd.events=POLLIN;
pfd.revents=0;
int p=0;
while(p<1) {
p=poll(&pfd,1,1000);
std::cout<<"poll "<<p<<pfd.revents; //prints 0 0 in infinite loop
std::cout.flush();
};
memset(wcmd,0,128);
len=recv(s,buf,255,0);
std::cout<<"recv "<<len;
close(s);
return 0;
}
Result is socket 3 bind 0 send 52 0 poll 00 poll 00 ...
Thanks
I want to have my Zedboard return a numeric value using the Xilinx lwIP example as a base but no matter what I do I can't figure out what stores the data received or transmitted.
I have found the void type payload but I don't know what to do with it.
Snapshot of one instance of payload and a list of lwIP files
Below is the closest function to my goal:
err_t recv_callback(void *arg, struct tcp_pcb *tpcb,
struct pbuf *p, err_t err){
/* do not read the packet if we are not in ESTABLISHED state */
if (!p) {
tcp_close(tpcb);
tcp_recv(tpcb, NULL);
return ERR_OK;
}
/* indicate that the packet has been received */
tcp_recved(tpcb, p->len);
/* echo back the payload */
/* in this case, we assume that the payload is < TCP_SND_BUF */
if (tcp_sndbuf(tpcb) > p->len) {
err = tcp_write(tpcb, p->payload, p->len, 1);
//I need to change p->paylod but IDK where it is given a value.
} else
xil_printf("no space in tcp_sndbuf\n\r");
/* free the received pbuf */
pbuf_free(p);
return ERR_OK;
}
Any guidance is appreciated.
Thanks,
Turtlemii
-I cheated and just made sure that the function has access to Global_tpcb from echo.c
-tcp_write() reads in an address and displays each char it seems.
void Print_Code()
{
/* Prepare for TRANSMISSION */
char header[] = "\rSwitch: 1 2 3 4 5 6 7 8\n\r"; //header text
char data_t[] = " \n\r\r"; //area for storing the
data
unsigned char mask = 10000000; //mask to decode switches
swc_value = XGpio_DiscreteRead(&SWCInst, 1); //Save switch values
/* Write switch values to the LEDs for visual. */
XGpio_DiscreteWrite(&LEDInst, LED_CHANNEL, swc_value);
for (int i =0; i<=7; i++) //load data_t with switch values (0/1)
{
data_t[8+2*i] = '0' + ((swc_value & mask)/mask); //convert one bit to 0/1
mask = mask >> 1;//move to next bit
}
int len_header = *(&header + 1) - header; //find the length of the
header string
int len_data = *(&data_t + 1) - data_t; //find the length of the data string
tcp_write(Global_tpcb, &header, len_header, 1); //print the header
tcp_write(Global_tpcb, &data_t, len_data, 1); //print the data
}
I am currently trying to send UDP datagrams from my Arduino to a server. I researched a bit online and found some code, which helped me to send them via a domain. Which works fine. But in my case I need to send it to a IP address, instead of a domain name (because my server doesn't have a domain). In this case I use the Ethercard library.
#include <EtherCard.h>
static byte mymac[] = { 0x1A,0x2B,0x3C,0x4D,0x5E,0x6F };
byte Ethernet::buffer[700];
static uint32_t timer;
const char website[] PROGMEM = "name.tld";
const int dstPort PROGMEM = 54321;
const int srcPort PROGMEM = 54321;
void setup () {
Serial.begin(9600);
// Change 'SS' to your Slave Select pin, if you arn't using the default pin
if (ether.begin(sizeof Ethernet::buffer, mymac, SS) == 0)
Serial.println( "Failed to access Ethernet controller");
if (!ether.dhcpSetup())
Serial.println("DHCP failed");
ether.printIp("IP: ", ether.myip);
ether.printIp("GW: ", ether.gwip);
ether.printIp("DNS: ", ether.dnsip);
//if (!ether.dnsLookup(website))
// Serial.println("DNS failed");
ether.printIp("SRV: ", ether.hisip);
}
char textToSend[] = "Hello";
void loop () {
if (millis() > timer) {
timer = millis() + 5000;
//static void sendUdp (char *data,uint8_t len,uint16_t sport, uint8_t *dip, uint16_t dport);
ether.sendUdp(textToSend, sizeof(textToSend), srcPort, ether.hisip, dstPort );
}
}
This is my code for sending something to a domain.
I assume you are using this library.
https://github.com/njh/EtherCard
The README explains how to send UDP datagrams. You want to use uint8_t parseIp(uint8_t *bytestr, const char *str) to format a destination IP address.
char payload[] = "My UDP message";
uint8_t nSourcePort = 1234;
uint8_t nDestinationPort = 5678;
uint8_t ipDestinationAddress[IP_LEN];
ether.parseIp(ipDestinationAddress, "192.168.0.200");
ether.sendUdp(payload, sizeof(payload), nSourcePort, ipDestinationAddress, nDestinationPort);
i just started the project which requiers to connect ADXL345 to my Atmega16. I want to put device id on screen and read axis. So far i cant communicate with ADXL345. ON LCD only appears 0 I would be gratefull for any help.
#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#include "hd44780.h"
#define F_CPU 1000000UL
/*-----------------------Rejestry ADXL345---------------------*/
char POWER_CTL = 0x2D; //Power Control Register 0x08 measurement
char DATA_FORMAT = 0x31;
char BW_RATE = 0X2C;
char FIFO = 0x38; //fifo ctl
char DATAX0 = 0x32; //X-Axis Data 0
char DATAX1 = 0x33; //X-Axis Data 1
char DATAY0 = 0x34; //Y-Axis Data 0
char DATAY1 = 0x35; //Y-Axis Data 1
char DATAZ0 = 0x36; //Z-Axis Data 0
char DATAZ1 = 0x37; //Z-Axis Data 1
char DEVICEID = 0x00;
#define Read_Byte_SPI( addr ) ADXL_write( 0x80 | addr , 0xFF );
/*------------------PORTY SPI---------------*/
#define SPI_CS PB4
#define DDR_SPI DDRB
#define DD_MOSI PB5
#define DD_MIOS PB6
#define DD_SCK PB7
/*vcc<->vs*/
//--------------------------------------Funkcje-------------------
unsigned int init_port(void) //ports 4 lcd
{DDRD =0x00; PORTD =0x07 ; }
/*function 4 lcd*/
static void lcd( int a){ LCD_LOCATE(2,0); char buff[2]; char tab[2]; /*itoa(a,buff,10);*/ sprintf(a, %d", buff); lcd_puts(buff);
}
/**
* This writes to a register with the data passed to the address passed
* #param unsigned char cReg - the address of the register you wish to write to
* #param unsigned char cData - the data you wish to write to the register
*/
unsigned char ADXL_write(unsigned char cReg, unsigned char cData){
set_spics();
/* Start transmission send register */
SPDR = cReg;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)))
{ /* NOOP */ }
SPDR = cData;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)))
{ /* NOOP */ }
clear_spics();
return SPDR;
}
uint8_t ADXL_read(unsigned char addr) { // read ADXL345 - 128+ addrs, back 8 bits - found this in another topic
int8_t ans;
set_spics();
SPDR = 0x08 | addr;
loop_until_bit_is_set(SPSR, SPIF);
SPDR = 0xFF;
loop_until_bit_is_set(SPSR, SPIF);
ans = SPDR;
clear_spics();
return(ans);}
//inicjalizacjia SPI
void Init_SPI(){
// make the MOSI, SCK, and SS pins outputs
DDRB |= ( 1 << DD_MOSI ) | ( 1 << DD_SCK ) | ( 1 << SPI_CS );
DDRB &= ~( 1 << DD_MIOS );
/* Enable SPI, Master, set clock rate fck/128 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);
}
//Control SS=CHIP SELECT ADXL345
void clear_spics(){
PORTB |= _BV(SPI_CS); // high
_delay_ms(30);}
void set_spics(){
PORTB &=~ _BV(SPI_CS); // low
_delay_ms(30);}
void ADXL_init(void){
//init ADXL
ADXL_write(DATA_FORMAT,0x08); //pełna rozdzielczość DATASHEET STRONA 26 4SPI
ADXL_write(BW_RATE, 0x0A) ; //100hz
ADXL_write(POWER_CTL,0x08);
ADXL_write(FIFO, 0); //FIFO Wylacozny
}
/*------------------------główna petla---------------------------*/
int main(void)
{
/* tab for strings */
char str1[] = "Czujnik ADXL 345";
/* init lcd*/
lcd_init();
/* LCD UP */
LCD_DISPLAY(LCDDISPLAY);
LCD_CLEAR;
LCD_LOCATE(1,1);
lcd_puts(str1);
init_port();/*port init*/
Init_SPI();//SPIUP
_delay_ms(50);
ADXL_init(); //ADXL345 config
_delay_ms(50);
while(1)
{
int8_t k;
k=Read_Byte_SPI( DEVICEID );
lcd(k);
_delay_ms(5000);
k=ADXL_read(DATAX0);
lcd(k);
_delay_ms(5000);
}
`>
I am writing a small program that sends and receive multicast packets.I need to set the outgoing interface with its name (e.g. eth0) rather than its address. Therefore I have to use struct ip_mreqn (rather than struct in_addr) so that I could use its imr_ifindex field to set the interface index (which I can get using interface's name).
However for some reason it doesn't work. The call to setsockopt() works fine but the following call to sendto() returns "Invalid argument" error. Of course the error disappears if I replace ip_mreqn with in_addr and use interface's address instead.
Following is my code:
sd = socket(AF_INET, SOCK_DGRAM, 0);
struct ip_mreqn addr;
addr.imr_ifindex = if_nametoindex("eth0");
setsockopt(sd, IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr);
struct sockaddr_in sock_addr;
memset((char *) &sock_addr, 0, sizeof(sock_addr));
sock_addr.sin_family = AF_INET;
sock_addr.sin_port = destination_port;
sock_addr.sin_addr.s_addr = destination_address;
char msg[] = "abc";
while (sendto(sd, msg, sizeof(msg), 0, reinterpret_cast<const sockaddr*>(&sock_addr),
sizeof(sock_addr)) < 0)
throw std::runtime_error(strerror(errno));
Is there any problem in using struct ip_mreqn when setting IP_MULTICAST_IF? Has anyone got any idea? Really appreciate help. Thanks.
Note that destination port and address are already in network byte order.
From tldp's multicast howto:
Usually, the system administrator specifies the default interface multicast datagrams should be sent from. The programmer can override this and choose a concrete outgoing interface for a given socket with this option.
struct in_addr interface_addr;
setsockopt (socket, IPPROTO_IP, IP_MULTICAST_IF, &interface_addr, sizeof(interface_addr));
Just an index to an interface doesn't suffice according to them.
Edit:
You're maybe confusing IP_MULTICAST_IF with IPV6_MULTICAST_IF, the latter takes an unsigned integer to denote the interface number (see man 7 ipv6).
Edit:
As it turns out the example given works as expected. Here's my full test case:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <sys/socket.h>
int main()
{
int sd = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in sa = {0};
struct ip_mreqn addr = {{0}};
char msg[] = "abc";
addr.imr_ifindex = if_nametoindex("eth0");
setsockopt(sd, IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr));
sa.sin_family = AF_INET;
sa.sin_port = 8653;
inet_pton(AF_INET, "224.255.255.5", &sa.sin_addr);
if (sendto(sd, msg, sizeof(msg), 0, (void*)&sa, sizeof(sa)) < 0) {
perror("bugger");
return 1;
}
return 0;
}
In the code example of the answer, don't forget to htons() the destination port in .sin_port