getaddrinfo on raspbian returns only loopback IP, same code on OS X multiple - raspbian

I have a short test program to fetch the IP address of the local machine. On Raspbian, only the loopback address is returned, while the same code on OS X return both normal and loopback IPs.
The code is
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <errno.h>
using namespace std;
int main (int argc, char * const argv[]) {
char hostname[128];
int result = gethostname(hostname, 127);
if (result != 0) {
cout << "FATAL: gethostname failed: " << result << errno;
return -1;
}
cout << "Host name is " << hostname << endl;
struct addrinfo hints, *res;
int errcode;
char addrstr[100];
void *ptr;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags |= AI_CANONNAME;
errcode = getaddrinfo(hostname, NULL, &hints, &res);
if (errcode != 0) {
perror("getaddrinfo");
return -1;
}
while(res) {
inet_ntop(res->ai_family, res->ai_addr->sa_data, addrstr, 100);
switch(res->ai_family) {
case AF_INET:
ptr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
break;
case AF_INET6:
ptr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
break;
default:
cout << "Unknown family" << endl;
}
inet_ntop(res->ai_family, ptr, addrstr, 100);
printf("IPV%d address: %s (%s)\n", res->ai_family == PF_INET6 ? 6 : 4, addrstr, res->ai_canonname);
res = res->ai_next;
}
return 0;
}
On OS X I get:
[Coyote]collector$ ./quick
Host name is Coyote.local
IPV4 address: 192.168.1.108 (coyote.local)
IPV6 address: fe80::223:dfff:fea0:a230 (coyote.local)
But on Raspbian I only get:
pi:~$ ./quick
Host name is pi
IPV4 address: 127.0.1.1 (pi)
yet
pi:~$ ifconfig
eth0 Link encap:Ethernet HWaddr b8:27:eb:62:15:fc
inet addr:192.168.1.162 Bcast:192.168.1.255 Mask:255.255.255.0
[...]
What do I need to do on Raspbian to get the correct result?

This is probably due to the contents of your /etc/hosts file. If your goal is to obtain the ip addresses of the system, consider using getifaddrs instead. It's of BSD origin, but works on Linux as well.
If you want for sure to know which address will be used when you connect somewhere, the best way to do it than to connect and then obtain the address using getsockname. The other option would be to read the routing tables.
Also, getnameinfo is usually a better choice than inet_ntop.

Related

How can I modify my code to read from a file input in client and then communicate it to a server?

Code:
//server.c
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <WinSock2.h>
#include <Windows.h>
#define SCK_VERSION 0x0202
int main()
{
//declare sockets first
SOCKET ConSock; // used for connection, hence the name
SOCKET ListenSock; // used for listening from the server
SOCKADDR_IN address; //socket address
int addrsize = sizeof(address);
long ok;
char MESSAGE[200];
char reply[200];
WSADATA WSD;
WORD DllVersion;
DllVersion = MAKEWORD(2,1);
ok = WSAStartup(DllVersion, &WSD);
//start creating our sockets
ConSock = socket(AF_INET, SOCK_STREAM, NULL);
address.sin_addr.s_addr = inet_addr("127.0.0.1");
address.sin_family = AF_INET;
address.sin_port = htons(10103);
ListenSock = socket(AF_INET, SOCK_STREAM, NULL);
bind(ListenSock, (SOCKADDR*)&address, sizeof(address));
listen(ListenSock, SOMAXCONN);
printf("Server waiting for connections\n\n");
for(;;){
if (ConSock = accept(ListenSock, (SOCKADDR*)&address, &addrsize))
{
ok = recv(ConSock, MESSAGE, sizeof(MESSAGE),NULL);
printf("\nClient says:\t %s", MESSAGE);
printf("\nEnter reply:\t");
gets(reply);
ok = send(ConSock,reply,200,NULL);
}
}
}
//client.c
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <WinSock2.h>
#include <Windows.h>
#define SCK_VERSION 0x0202
int main()
{
SOCKET sock;
SOCKADDR_IN address;
long ok;
char MESSAGE[200];
char reply[200];
WSADATA WSD;
WORD DllVersion;
DllVersion = MAKEWORD(2,1);
ok = WSAStartup(DllVersion, &WSD);
address.sin_addr.s_addr = inet_addr("127.0.0.1");
address.sin_family = AF_INET;
address.sin_port = htons(10103);
for(;;)
{
sock = socket(AF_INET,SOCK_STREAM,NULL);
connect(sock, (SOCKADDR*)&address, sizeof(address));
printf("\nEnter Message:\t");
gets(MESSAGE);
ok = send(sock,MESSAGE,200,NULL);
ok = recv(sock,reply,sizeof(reply),NULL);
printf("\nServer says:\t %s",reply);
}
}
//makefile
server:
g++ server.c -o server
client:
g++ client.c -o client
clean:
rm server
rm client
all: server client
This runs with -lwsock32 and it does a good job, but I need to adjust it now to comunicate some data from a file, the data is mostly values of voltages, currents, active reactive power, etc.
I have been trying for quite some time and I cannot seem to adjust it.
If you can rewrite it in terms of the client communicating the values(that are stored in a file) to the server, that will be great. Any help is greatly appreciated, as I am not being succesful currently.

Read status of FT245RL pins

Sorry for my ignorance but I am very new in FTDI chip Linux software development.
I have module based on FT245RL chip, programmed to be 4 port output (relays) and 4 port opto isolated input unit.
I found out in Internet program in C to turn on/off relays connected to outputs D0 to D3. After compiling it works properly. Below draft of this working program:
/* switch4.c
* # gcc -o switch4 switch4.c -L. -lftd2xx -Wl,-rpath,/usr/local/lib
* Usage
* # switch4 [0-15], for example # switch4 1
* */
#include <stdio.h>
#include <stdlib.h>
#include "./ftd2xx.h"
int main(int argc, char *argv[])
{
FT_STATUS ftStatus;
FT_HANDLE ftHandle0;
int parametr;
LPVOID pkod;
DWORD nBufferSize = 0x0001;
DWORD dwBytesWritten;
if(argc > 1) {
sscanf(argv[1], "%d", ¶metr);
}
else {
parametr = 0;
}
FT_SetVIDPID(0x5555,0x0001); // id from lsusb
FT_Open(0,&ftHandle0);
FT_SetBitMode(ftHandle0,15,1);
pkod=&parametr;
ftStatus = FT_Write(ftHandle0,pkod,nBufferSize,&dwBytesWritten);
ftStatus = FT_Close(ftHandle0);
}
My question is. How can I read in the same program, status of D4 to D7 pins, programmed as inputs? I mean about "printf" to stdout the number representing status (zero or one) of input pins (or all input/output pins).
Can anybody help newbie ?
UPDATE-1
This is my program with FT_GetBitMode
// # gcc -o read5 read5.c -L. -lftd2xx -Wl,-rpath,/usr/local/lib
#include <stdio.h>
#include <stdlib.h>
#include "./ftd2xx.h"
int main(int argc, char *argv[])
{
FT_STATUS ftStatus;
FT_HANDLE ftHandle0;
UCHAR BitMode;
FT_SetVIDPID(0x5555,0x0001); // id from lsusb
ftStatus = FT_Open(0,&ftHandle0);
if(ftStatus != FT_OK) {
printf("FT_Open failed");
return;
}
FT_SetBitMode(ftHandle0,15,1);
ftStatus = FT_GetBitMode(ftHandle0, &BitMode);
if (ftStatus == FT_OK) {
printf("BitMode contains - %d",BitMode);
}
else {
printf("FT_GetBitMode FAILED!");
}
ftStatus = FT_Close(ftHandle0);
}
But it returns "FT_GetBitMode FAILED!" instead value of BitMode
FT_GetBitMode returns the instantaneous value of the pins. A single byte will be
returned containing the current values of the pins, both those which are inputs and
those which are outputs.
Source.
Finally I found out whats going wrong. I used incorrect version of ftdi library. The correct version dedicated for x86_64 platform is located here:
Link to FTDI library

configuration of adafruit ultimate gps from raspberry pi does not work

I connected my ultimate gps breakout to my raspberry pi using the USB to TTL serial cable. Using C code I can easily connect to and read NMEA sentences from the GPS. But when I write configuration commands such as PMTK220 to set the update rate, they are ignored. I should get back a PMTK_ACK reporting success or failure, but it is not forthcoming. The problem also occurs when I use terminal windows. ie. I run:
while (true) do cat -A /dev/ttyUSB0 ; done
in one terminal, and get a stream of $GPGGA, $GPGSA, $GPRMC etc messages. In another terminal I run:
echo "$PMTK220,200*2C\r\n" > /dev/ttyUSB0
The NMEA messages continue but there is no PMTK001 coming back. Any ideas?
Ok, here's some code (inspired by gpsd source) that demonstrates sending a configuration message and getting an acknowledgement:
#define _BSD_SOURCE
#include <stdio.h>
#include <stdarg.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <semaphore.h>
#include <string.h>
#ifndef CRTSCTS
# ifdef CNEW_RTSCTS
# define CRTSCTS CNEW_RTSCTS
# else
# define CRTSCTS 0
# endif /* CNEW_RTSCTS */
#endif /* !CRTSCTS */
int main (int argc, char **argv) {
int const baudr = B9600, mode = O_RDWR | O_NONBLOCK | O_NOCTTY;
int const fd = open("/dev/ttyUSB0", mode);
assert (fd != -1);
ioctl(fd, (unsigned long)TIOCEXCL);
struct termios ttyOld, ttyNew;
assert(tcgetattr(fd, &ttyOld) != -1);
ttyNew = ttyOld;
ttyNew.c_cflag &= ~(CSIZE | PARENB | PARODD | CRTSCTS | CSTOPB);
ttyNew.c_cflag |= CREAD | CLOCAL | CS8;
ttyNew.c_iflag = ttyNew.c_oflag = 0;
ttyNew.c_lflag = ICANON;
cfsetispeed(&ttyNew, baudr);
cfsetospeed(&ttyNew, baudr);
assert(tcsetattr(fd, TCSANOW, &ttyNew) != -1);
tcflush(fd, TCIOFLUSH);
usleep(200000);
tcflush(fd, TCIOFLUSH);
int const oldfl = fcntl(fd, F_GETFL);
assert (oldfl != -1);
fcntl(fd, F_SETFL, oldfl & ~O_NONBLOCK);
tcdrain(fd);
printf("port opened baudr=%d mode=%d i=%d o=%d c=%d l=%d fl=%d\n", baudr, mode, ttyNew.c_iflag, ttyNew.c_oflag, ttyNew.c_cflag, ttyNew.c_lflag, oldfl);
unsigned char buf[2048];
int count = 0;
while(++count < 20) {
if (count == 4) {
char const *const cmd = "$PMTK220,200*2C\r\n";
int const n = strlen(cmd);
assert(write(fd, cmd, n) == n);
tcdrain(fd);
printf("wrote command %d: %s\n", n, cmd);
}
int const n = read(fd, buf, sizeof(buf));
buf[(n >= sizeof(buf)) ? (sizeof(buf) - 1) : n] = 0;
printf(buf);
}
tcsetattr(fd, TCSANOW, &ttyOld);
close(fd);
}
with results:
pi#pi01 ~/c $ ./test
port opened baudr=13 mode=2306 i=0 o=0 c=3261 l=2 fl=2050
$GPGGA,175748.089,,,,,0,00,,,M,,M,,*71
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPRMC,175748.089,V,,,,,0.00,0.00,260715,,,N*43
wrote command 17: $PMTK220,200*2C
$GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32
$PMTK001,220,2*31
$GPGGA,175749.089,,,,,0,00,,,M,,M,,*70
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,1,1,01,11,,,31*7A
$GPRMC,175749.089,V,,,,,0.00,0.00,260715,,,N*42
$GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32
$GPGGA,175750.089,,,,,0,00,,,M,,M,,*78
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPRMC,175750.089,V,,,,,0.00,0.00,260715,,,N*4A
$GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32
$GPGGA,175751.089,,,,,0,00,,,M,,M,,*79
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPRMC,175751.089,V,,,,,0.00,0.00,260715,,,N*4B
$GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32
$GPGGA,175752.089,,,,,0,00,,,M,,M,,*7A
pi#pi01 ~/c $

how to perform ssdp communicationbetween upnp devices

i am trying to implement the upnp level communication between the devices .. but facing problem in getting the response message .and more over on sending the ssdp:discovery multicast not able to recieve the messages from the devices ... please guide me through i am completely newto this topic
pre-requisite done by me :
1.able to send the M-Search ..and notify message on the network .. and have confirmed via wireshark
2.gone through the upnp architecture related pdf
response got in wireshark :
when ever i am sending the message i am getting the icmp error message that destination is not reachable ..
< client side code > is the first one and second one is the for time being i am just sending up the data on local host
#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"
/* diep(), #includes and #defines like in the server */
#define BUFLEN 512
#define NPACK 10
#define PORT 1900
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, "\n");
if (sendto(s, buf, BUFLEN, 0, &si_other, slen)==-1)
diep("sendto()");
}
close(s);
return 0;
}
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFLEN 512
#define NPACK 10
#define PORT 1900
void diep(char *s)
{
perror(s);
exit(1);
}
int main(void)
{
struct sockaddr_in si_me, 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_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, &si_me, sizeof(si_me))==-1)
diep("bind");
for (i=0; i<NPACK; i++) {
if (recvfrom(s, buf, BUFLEN, 0, &si_other, &slen)==-1)
diep("recvfrom()");
printf("Received packet from %s:%d\nData: %s\n\n",
inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port), buf);
}
close(s);
return 0;
}
The individual lines in you M-SEARCH need to have "\r\n" at the end of each line, not just a "\n". Your system may just be sending "\n" across the wire. Check the bytes you're sending for a 13 followed by a 10. That's "\r\n".

How to print HFS Volume header

Any one please give code snippet for how to print volume header of HFS+ disk.
I’ve written a small program (based on hfs-183.1) that prints some of the information declared in struct HFSPlusVolumeHeader. The program must be run as root — for instance, via sudo(8):
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <hfs/hfs_format.h>
#include <libkern/OSByteOrder.h>
int main(void) {
int fd;
struct stat stat_buf;
struct HFSPlusVolumeHeader vheader;
const char *vname = "/dev/rdisk0s2";
if (lstat(vname, &stat_buf) == -1) {
fprintf(stderr, "Couldn't stat %s\n", vname);
perror(NULL);
exit(1);
}
if ((stat_buf.st_mode & S_IFMT) != S_IFCHR) {
fprintf(stderr, "%s is not a raw char device\n", vname);
perror(NULL);
exit(2);
}
fd = open(vname, O_RDONLY);
if (fd == -1) {
fprintf(stderr, "%s couldn't be opened for reading\n", vname);
perror(NULL);
exit(3);
}
// The volume header starts at offset 1024
if (pread(fd, &vheader, sizeof vheader, 1024) != sizeof vheader) {
fprintf(stderr, "couldn't read %s's volume header\n", vname);
perror(NULL);
exit(4);
}
printf("fileCount = %u\n"
"folderCount = %u\n"
"blockSize = %u\n"
"totalBlocks = %u\n"
"freeBlocks = %u\n",
OSSwapBigToHostInt32(vheader.fileCount),
OSSwapBigToHostInt32(vheader.folderCount),
OSSwapBigToHostInt32(vheader.blockSize),
OSSwapBigToHostInt32(vheader.totalBlocks),
OSSwapBigToHostInt32(vheader.freeBlocks));
close(fd);
return 0;
}
The header file <hfs/hfs_format.h> declares struct HFSPlusVolumeHeader. See this file for the complete list of fields inside a HFS+ volume header.
The system call getattrlist() might give you the information you need.