I'm a little stuck with something right now:
Trying to figure out how to calculate the network/broadcast address for the following CIDR IP: 10.20.30.45/13.
As far as I can see, the fact that the network part of this IP is 13 bits big, tells us that the address hast got to be changed beginning with the seccond oktett when determining the network address
-> 10.X.0.0
But what will X be, and how can I calculate X?
You can convert 10.20.30.45 to binary and /13 to binary, which is 255.248.0.0.
10.20.30.45 in binary would be 00001010 00010100 00011110 00101101
255.248.0.0 is 11111111 11111000 00000000 00000000
Then compare them:
00001010 00010100 00011110 00101101
11111111 11111000 00000000 00000000
______________________________________
00001010 00010000 00000000 00000000 => back to decimal is 10.16.0.0
To get the broadcast address you have to do a binary inversion of the CIDR or Netmask Address.
Or you can you this CIDR converter to automate it for you.
In C(++):
#ifdef __FreeBSD__
#include <sys/socket.h>
#endif
#include <arpa/inet.h>
#include <netinet/in.h>
#include <cassert>
#include <cstdint>
#include <iostream>
int main() {
in_addr net, broadcast;
int bits = inet_net_pton(AF_INET, "10.20.30.45/13", &net, sizeof(net));
assert((bits != -1)); // assert that inet_net_pton understood us
// Apply CIDR mask to address to get the network
if (bits > 0) { // u32 << 32 is undefined
uint32_t mask = htonl((0xFFFFFFFFu) << (32 - bits));
net.s_addr &= mask;
}
broadcast = net;
// Do the same for broadcast
if (bits < 32) {
uint32_t mask = htonl((0xFFFFFFFFu) >> bits);
broadcast.s_addr |= mask;
}
std::cout << "Network: " << inet_ntoa(net) << std::endl;
std::cout << "Broadcast: " << inet_ntoa(broadcast) << std::endl;
}
Outputs:
Network: 10.16.0.0
Broadcast: 10.23.255.255
Related
I did everything. I shutoff the bits to disable the output processing in the termios structure, properly set the baud rate and character size and disabled parity, flush the output and input buffers before sending. Even after all this linux serial still doesn't work the way I want it to. Canonical mode is not even on in the first place, everything is raw bytes. Btw I am using arch linux connected to an arduino nano with an usb cable which will receive the bytes from PC and display them on a lcd. When I send a byte from PC, e.g char 'A', it apears to get corrupted during the transmisson process, and arduino displays the corrupted byte. Everytime I send character 'A' it shows ascii value 254 on the lcd which is clearly wrong. How do I solve this problem?
My C code on pc:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int serial_port = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
getchar();
struct termios old_tty;
struct termios new_tty;
if (tcgetattr(serial_port, &new_tty) != 0) {
printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
return 1;
}
old_tty = new_tty;
new_tty.c_cflag &= ~(CSTOPB | CSIZE | PARENB);
new_tty.c_cflag |= CS8;
new_tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
new_tty.c_oflag &= ~OPOST;
new_tty.c_iflag &= ~(IXON | IXOFF | IXANY | INPCK | ISTRIP);
//new_tty.c_cc[VMIN] = 0;
//new_tty.c_cc[VTIME] = 0;
cfsetispeed(&new_tty, B9600);
cfsetospeed(&new_tty, B9600);
if (tcsetattr(serial_port, TCSANOW, &new_tty) != 0) {
printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
return 1;
}
tcflush(serial_port, TCIOFLUSH);
unsigned char val = 'A';
write(serial_port, &val, sizeof(val));
getchar();
tcsetattr(serial_port, TCSANOW | TCSADRAIN, &old_tty);
close(serial_port);
return 0;
}
Code on Arduino:
void setup() {
lcd.begin(16, 2); // begins connection to the LCD module
lcd.backlight(); // turns on the backlight
lcd.clear();
lcd.setCursor(0, 0);
Serial.begin(9600);
lcd.print("Init done");
}
void loop() {
if (Serial.available() > 0) {
uint8_t x = Serial.read();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("I received: ");
lcd.setCursor(0, 1);
lcd.print(x);
}
}
I have written a program on Arduino IDE to make an HTML page. It is getting compiled as well as getting upload on my nodemcu. But I get no any HTML page in browser whenever I try to enter into it with the IP address serial provided on the serial monitor. Kindly help me to find the problem if there is any either in my code or in the headerfile which is in current directory . Following is my code,
#include<ESP8266WiFi.h>
#include<WiFiClient.h>
#include<ESP8266WebServer.h>
#include "index.h"
const char * ssid = "Nadeem";
const char *password = "hamzalaiba";
ESP8266WebServer server(80);
void handleRoot() {
String s = MAIN_page; //Read HTML contents
server.send(200, "text/html", s); //Send web page
}
void setup(){
Serial.begin(9600);
delay(10);
Serial.print("Connecting to\n");
Serial.print(ssid);
WiFi.begin(ssid,password);
while(WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("Wifi connected");
delay(10);
Serial.print("Your server IP address: ");
Serial.println(WiFi.localIP());
server.on("/",handleRoot);
server.begin();
Serial.println("Server Started");
}
void loop(){
server.handleClient();
}
The headerfile 'index.h' contains following codes ,
const char MAIN_PAGE[] PROGMEM = R"=====(
<HTML>
<HEAD>
<TITLE>My first web page</TITLE>
</HEAD>
<BODY>
<CENTER>
<B>Hello Zain.... </B>
</CENTER>
</BODY>
</HTML>
)=====";
The output I get on serial monitor have following stuff,
......
Wifi connected
Your server IP address: 192.168.10.13
Server Started
--------------- CUT HERE FOR EXCEPTION DECODER ---------------
Exception (3):
epc1=0x4000bf64 epc2=0x00000000 epc3=0x00000000 excvaddr=0x4023d559 depc=0x00000000
.>>>stack>>>
ctx: cont
sp: 3ffffd00 end: 3fffffc0 offset: 0190
3ffffe90: 00000001 3ffee38c 4023d559 4020574b
3ffffea0: 3ffef450 00000001 3ffef24c 402031aa
3ffffeb0: 3fffff00 3fffff10 80fffef0 40201b50
3ffffec0: 00000001 40208230 3ffffef0 402081fe
3ffffed0: 3fffff10 3ffee3a8 3ffef24c 401000e1
3ffffee0: 3ffef24c 3ffee3a8 3ffef24c 40201b88
3ffffef0: 3ffe0000 3fff0000 80000001 80fe84ec
3fffff00: 3ffef24c 3ffee3a8 3ffee368 402031fe
3fffff10: 0000002f 80000000 81fefb00 0000008f
3fffff20: 80005054 388a21b4 40100200 00002ade
3fffff30: 3ffee3a8 00000000 00000001 00000001
3fffff40: 00000001 3ffef24c 3ffee368 3ffee500
3fffff50: 00000001 3ffee38c 3ffee368 3ffee500
3fffff60: 00000001 3ffee38c 3ffee368 40203497
3fffff70: 00000000 00000000 00001388 80efeffe
3fffff80: 00000000 00000000 00000001 40100170
3fffff90: 3fffdad0 00000000 3ffee4c0 40203538
3fffffa0: 3fffdad0 00000000 3ffee4c0 4020668c
3fffffb0: feefeffe feefeffe 3ffe84ec 40100ba1
<<<stack<<<
--------------- CUT HERE FOR EXCEPTION DECODER ---------------
V)⸮L⸮⸮D⸮⸮Connecting to
Nadeem...........
Wifi connected
Your server IP address: 192.168.10.13
Server Started
I want send some string to PC via serial bus. In cute com its displaying the string along with some chars are missing and at the starting and end of the string its appending some hex numbers. Why this problem occurring I don't know please help in this issue. My code is here.
#include <avr/io.h>
#include <string.h>
#include <avr/interrupt.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#define USART_BAUDRATE 9600 // Baud Rate value
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
void usart_init() {
//Enable communication in duplex mode
UCSR1A = (1 << U2X1);
UCSR1B |= (1 << RXEN1) | (1 << TXEN1); // Turn on the transmission and reception circuitry
UCSR1C &= ~(1 << UMSEL1);
UCSR1C |= (1<<USBS1) | (1 << UCSZ10) | (1 << UCSZ11);
UBRR1L = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
UBRR1H = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value..
}
void serial_write(unsigned char data) {
while(!(UCSR1A & (1<<UDRE1)))
;
UDR1 = data;
_delay_ms(10);
}
void transmitString(unsigned char *str) {
int i;
for(i=0;i<strlen(str);i++) {
serial_write(str[i]);
_delay_ms(1);
}
}
int main() {
cli();
usart_init();
unsigned char buffer[20];
strcpy(buffer, "Walk Alone");
while(1) {
transmitString(buffer);
//_delay_ms(250);
}
return 0;
}
Firstly, this question belongs in http://electronics.stackexchange.com
To answer your question, functions strcpy() and strlen() expect a char * and not unsigned char * check here
what happens when a UDP packet is sent to a host using sendto().
all the bits i am sending are sent(known from the return value).immediately i use a recvfrom() which does not output anything but program do not exit(i.e no return value).
I think that the program must exit if no reply is recieved.
what will the replies for a UDP packet from a port.
is this packet blocked by firewall?? if yes then why is the return value of sendto is non-negative.
recvfrom() will block until a message is received unless you set the socket to non-blocking.
The interfaces you want to look for are
ioctl() with FIONBIO or O_NONBLOCK (depending your platform),
select() to wait for data to arrive, or timeout after a while
Also remember that the address and port number for sendto() usually be network-byte order, so look into ntohl and ntohs.
you must have some error in your client or server. try localhost first, so you avoid firewall problems
this is an example of nonblocking udp client/server I was using for my tests, it uses ioctl() to check if there is data to read on the socket, however if you want to do some serious application using epoll would be more efficient also you can specify timeout to wait in microseconds:
[null#localhost tests]$ cat udpserv.c
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>
#define BUFLEN 512
#define NPACK 15
#define PORT 9930
void diep(char *s)
{
printf("erno=%d errstr=%s\n",errno,strerror(errno));
perror(s);
exit(1);
}
int main(void)
{
struct sockaddr_in si_me, si_other;
int s,ret,nbytes, i, slen=sizeof(si_other);
char buf[BUFLEN];
if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
diep("socket");
memset((char *) &si_me, 0, sizeof(si_me));
si_me.sin_family = AF_INET;
si_me.sin_port = htons(PORT);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(s, (struct sockaddr*) &si_me, sizeof(si_me))==-1)
diep("bind");
fcntl(s, F_SETFL, fcntl(s, F_GETFL, 0) | O_NONBLOCK);
sleep(10);
for (i=0; i<NPACK; i++) {
ret=ioctl(s,FIONREAD,&nbytes);
if (ret==-1) {
printf("error on FIONREAD\n");
} else {
printf("nbytes=%d\n",nbytes);
}
if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr*) &si_other, &slen)==-1)
diep("recvfrom()");
printf("Received first half of packet from %s:%d\nData: %s\n\n",
inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port), buf);
}
close(s);
return 0;
}
[null#localhost tests]$ cat udpclient.c
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#define SRV_IP "127.0.0.1"
#define BUFLEN 200
#define NPACK 10
#define PORT 9930
/* diep(), #includes and #defines like in the server */
void diep(char *s)
{
perror(s);
exit(1);
}
int main(void)
{
struct sockaddr_in si_other;
int s, i, slen=sizeof(si_other);
char buf[BUFLEN];
if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
diep("socket");
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
if (inet_aton(SRV_IP, &si_other.sin_addr)==0) {
fprintf(stderr, "inet_aton() failed\n");
exit(1);
}
for (i=0; i<NPACK; i++) {
printf("Sending packet %d\n", i);
sprintf(buf, "This is packet %d\n", i);
if (sendto(s, buf, BUFLEN, 0, (struct sockaddr*) &si_other, slen)==-1)
diep("sendto()");
}
close(s);
return 0;
}
the sendto() is non negative because it returns number of bytes sent. check the man page for sendto
How can I send a datagram with an Ethernet trailer? If I use SocketType.Raw, I'll have to send the whole IP header and I have no idea how to do that.
Something like this perhaps?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <sys/ioctl.h>
int s;
unsigned char buffer[513];
struct sockaddr_ll socket_address;
int main ( void )
{
unsigned char seq;
unsigned int ra;
int length;
struct ifreq ifr;
s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (s == -1)
{
printf("error creating socket\n");
return(1);
}
memset(&ifr,0, sizeof(struct ifreq));
strncpy(ifr.ifr_name,"eth0",IFNAMSIZ);
if(ioctl(s, SIOCGIFINDEX, &ifr) < 0)
{
perror("ioctl SIOCGIFINDEX");
exit(1);
}
printf("index %d\n",ifr.ifr_ifindex);
printf("socket created\n");
memset(&socket_address,0,sizeof(socket_address));
socket_address.sll_family = PF_PACKET;
socket_address.sll_protocol = htons(ETH_P_ALL);
socket_address.sll_ifindex = ifr.ifr_ifindex;
if (bind(s, (struct sockaddr *)(&socket_address), sizeof(socket_address)) < 0)
{
perror("bind error");
exit(1);
}
printf("bound\n");
length=27;
memset(buffer,0,sizeof(buffer));
//destination
buffer[ 0]=0xFF;
buffer[ 1]=0xFF;
buffer[ 2]=0xFF;
buffer[ 3]=0xFF;
buffer[ 4]=0xFF;
buffer[ 5]=0xFF;
//source
buffer[ 6]=0x00;
buffer[ 7]=0x19;
buffer[ 8]=0xd1;
buffer[ 9]=0x02;
buffer[10]=0xdc;
buffer[11]=0xb3;
//length
buffer[12]=((length-14)>>8)&0xFF;
buffer[13]=((length-14)>>0)&0xFF;
//payload
buffer[14]=0x12;
buffer[15]=0x34;
for(ra=0;ra<20;ra++)
{
buffer[16]=ra;
if(send(s,buffer,length,0) < 0 )
{
printf("sendto failed\n");
break;
}
else
{
printf("sent\n");
}
}
close(s);
return(1);
}
That should give a raw packet that you can see on wireshark. if you want to have the ip eader, or make it a udp or something like that you can use this method and build the header yourself (it is trivial look at the rfcs or just use wireshark to look at a bunch of other packet headers). Note that for udp you do not have to compute a checksum 0x0000 is a valid checksum that is supposed to pass on through.
If all you want is a udp packet with zeros at the end that is somewhat the same, probably easier, let me know.
That trailer is used to pad ethernet frames to their minimum length (46 bytes of payload). So send a small UDP packet - smaller than 18 bytes (as IP + UDP is normally 28 bytes)