Date: Wed, 05 Jan 2000 13:31:28 -0500 From: "Douglas B. Quayle" <dquayle@slk.com> To: Matt Gostick <matt@crazylogic.net> Cc: freebsd-questions@freebsd.org Subject: Re: ioctl programming probs Message-ID: <38738E00.2A1B98AE@slk.com> References: <Pine.BSF.4.10.9912282005040.40430-100000@thunk.crazylogic.net>
next in thread | previous in thread | raw e-mail | index | archive | help
I had a friend who asked me for something similar, so I'll give you the code I wrote for him. This was build on a 3.2-RELEASE box. What I didn't know how to do, I learned from http://ccnga.uwaterloo.ca/~mvlioy/stuff/ipc_adv_tut.txt and Unix Network Programming. I would recommend compiling as follows: g++ -Wall -ansi -ggdb main.cc #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stddef.h> #include <iostream.h> extern "C" { #include <errno.h> #include <unistd.h> #include <netdb.h> #include <sys/param.h> #include <sys/types.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <net/if.h> #include <netinet/in.h> } union netaddr_t { unsigned long l; unsigned char b[sizeof(long)]; }; template <class errcode_t> class error { errcode_t ec; int err; unsigned long ln; public: error(errcode_t excpt, unsigned long l = 0, int errn = errno) : ec(excpt), err(errn), ln(l) { } error(const error<errcode_t> &e) : ec(e.ec), err(e.err), ln(e.ln) { } ~error(void) { } inline errcode_t code(void) const { return ec; } inline int operator()(void) const { return err; } inline unsigned long line(void) const { return ln; } }; enum err_t { Socket, Bind, IoCtl }; typedef error<err_t> err; typedef struct hostent hostent_t; typedef struct ifconf ifconf_t; typedef struct ifreq ifreq_t; typedef struct protoent protoent_t; typedef struct sockaddr sock_t; typedef struct sockaddr_in sockin_t; static const char *const TCP = "tcp"; static const short PORT = 3123; static const int SOCK_FAMILY = AF_INET, SOCK_MODE = SOCK_DGRAM; static const int SOCK_PROT = 0; int main(int argc, char **argv) { char ifcbuf[1024] = { 0 }; int result = 0, fd = -1, i = 1; ifconf_t ifc = { sizeof(ifcbuf), { ifcbuf }}; ifreq_t *ifr = 0; netaddr_t netaddr = { 0 }; sock_t dest; sockin_t sin; try { if((fd = socket(SOCK_FAMILY, SOCK_MODE, SOCK_PROT)) < 0) throw err(Socket, __LINE__); if(setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &i, sizeof(int)) < 0) throw err(Socket, __LINE__); memset((void *) &sin, 0, sizeof(sockin_t)); sin.sin_family = SOCK_FAMILY, sin.sin_port = htons(PORT), sin.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(fd, (sock_t *) &sin, sizeof(sockin_t)) < 0) throw err(Bind, __LINE__); if(ioctl(fd, SIOCGIFCONF, (char *) &ifc) < 0) throw err(IoCtl, __LINE__); for(i = ifc.ifc_len / sizeof(ifreq_t), ifr = ifc.ifc_req; --i >= 0; ifr++) { if(ioctl(fd, SIOCGIFFLAGS, (char *) ifr) < 0) continue; if(ifr -> ifr_flags & IFF_BROADCAST) { if(ioctl(fd, SIOCGIFADDR, (char *) ifr) < 0) throw err(IoCtl, __LINE__); else { memcpy((void *) &dest, (const void *) &ifr -> ifr_broadaddr, sizeof(sock_t)); netaddr.l = ((sockin_t *) &dest) -> sin_addr.s_addr; cout << "Interface " << (short) netaddr.b[0] << "." << (short) netaddr.b[1] << "." << (short) netaddr.b[2] << "." << (short) netaddr.b[3] << '\t'; } if(ioctl(fd, SIOCGIFBRDADDR, (char *) ifr) < 0) throw err(IoCtl, __LINE__); else { memcpy((void *) &dest, (const void *) &ifr -> ifr_broadaddr, sizeof(sock_t)); netaddr.l = ((sockin_t *) &dest) -> sin_addr.s_addr; cout << "Broadcast " << (short) netaddr.b[0] << "." << (short) netaddr.b[1] << "." << (short) netaddr.b[2] << "." << (short) netaddr.b[3] << endl; } } } } catch(const err e) { switch(e.code()) { case Bind: cerr << "Bind error "; break; case Socket: cerr << "Socket error "; break; case IoCtl: cerr << "Socket control error "; break; } cerr << "at " << e.line() << endl << strerror(e()) << endl; } if(fd >= 0) close(fd); return result; } Matt Gostick wrote: > I'm trying to make a simple little program that gets the ip address of a > given interface. I'm using ioctl to do this and am having a wierd problem > that I can't figure out. Any help is appretiated. > > >From what I understand about ioctl ... the below program should display > the interface name, ip address, destination address and the broadcast > address. Unfortuanely it's not. It's not crashing ... it just always > prints: > > name : lo0 > addr : 16.2.0.0 > dstaddr : 16.2.0.0 > broadaddr : 16.2.0.0 > > I've tried this on two different FreeBSD-3.2 machines with the same > result, even the same IP's. I've even tried switching the interface > names to something different, and am still getting the same IP's. > > I have searched newsgroups and mailing lists only to come up with no > solution. I was hoping that those familiar with ioctl under FreeBSD will > spot my mistake in a couple of seconds... :) I'm new to it so any help is > very much appretiated. > > /* --<get_if_ip.c>------------------------------------- */ > > #include <stdio.h> > #include <sys/types.h> > #include <sys/ioctl.h> > #include <sys/socket.h> > #include <net/if.h> > > int main (void) { > int fd; > struct ifreq ifr; > > /* open a socket to use for ioctl */ > if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { > perror("socket"); > return -1; > } > > strcpy(ifr.ifr_name, "lo0"); > > /* get if address */ > if (ioctl(fd, SIOCGIFADDR, &ifr, sizeof(ifr)) == -1) { > close(fd); > perror("ioctl"); > return -1; > } > > printf("name : %s\n", ifr.ifr_name); > printf("addr : %s\n", inet_ntoa(ifr.ifr_addr)); > printf("dstaddr : %s\n", inet_ntoa(ifr.ifr_dstaddr)); > printf("broadaddr : %s\n", inet_ntoa(ifr.ifr_broadaddr)); > > close(fd); > return 0; > } > > /* --<end get_if_ip.c>---------------------------------- */ > > Thanks, > Matt > > To Unsubscribe: send mail to majordomo@FreeBSD.org > with "unsubscribe freebsd-questions" in the body of the message To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-questions" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?38738E00.2A1B98AE>