From owner-freebsd-questions Wed Jan 5 10:31:56 2000 Delivered-To: freebsd-questions@freebsd.org Received: from nj-gate.slk.com (smtp2.slk.com [12.3.89.217]) by hub.freebsd.org (Postfix) with ESMTP id 5DAD1154BC for ; Wed, 5 Jan 2000 10:31:50 -0800 (PST) (envelope-from dquayle@slk.com) Received: by nj-gate.slk.com; id NAA21470; Wed, 5 Jan 2000 13:31:29 -0500 (EST) Received: from slkmail.net.slk.com(92.1.33.235) by nj-gate.slk.com via smap (4.0a) id xma021065; Wed, 5 Jan 00 13:30:39 -0500 Received: from slk.com (92.1.57.144 [92.1.57.144]) by slkmail.net.slk.com with SMTP (Microsoft Exchange Internet Mail Service Version 5.5.2232.9) id XA6SYT7K; Wed, 5 Jan 2000 13:26:12 -0500 Message-ID: <38738E00.2A1B98AE@slk.com> Date: Wed, 05 Jan 2000 13:31:28 -0500 From: "Douglas B. Quayle" Organization: Spear, Leeds & Kellogg X-Mailer: Mozilla 4.51 [en] (X11; I; FreeBSD 3.2-RELEASE i386) X-Accept-Language: en MIME-Version: 1.0 To: Matt Gostick Cc: freebsd-questions@freebsd.org Subject: Re: ioctl programming probs References: Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-questions@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG 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 #include #include #include #include extern "C" { #include #include #include #include #include #include #include #include #include } union netaddr_t { unsigned long l; unsigned char b[sizeof(long)]; }; template 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 &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; 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. > > /* --------------------------------------- */ > > #include > #include > #include > #include > #include > > 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; > } > > /* ------------------------------------ */ > > 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