|
|
1.1 root 1: /* $Header: xnsbfs.c,v 1.4 87/01/16 15:46:52 ed Exp $ */
2:
3: /*
4: * $Log: xnsbfs.c,v $
5: * Revision 1.4 87/01/16 15:46:52 ed
6: * Webster changes
7: *
8: * Revision 1.4 87/01/16 15:46:52 ed
9: * Added exit(0) for normal exit
10: *
11: * Revision 1.3 86/12/16 15:29:56 ed
12: * Add -a option to perform broadcast for Authentication servers
13: *
14: * Revision 1.2 86/07/29 06:39:27 jqj
15: * added some comments and code cleanup in main routine.
16: *
17: * Revision 1.1 86/06/27 13:14:38 jqj
18: * Initial revision
19: *
20: */
21:
22: /*
23: * XNS broadcast for servers:
24: * syntax: xnsbfs -a [xnshostaddress]
25: *
26: * With -a option, broadcast for Authentication servers,
27: * else Clearinghouse servers
28: * With no arguments, sends a broadcast query to all directly connected XNS
29: * networks looking for Clearinghouse servers
30: * With an argument, sends a query to the particular address specified.
31: *
32: * Cornell University
33: * Dept. of Computer Science
34: *
35: */
36:
37:
38: #include <sys/types.h>
39: #include <sys/time.h>
40: #include <sys/socket.h>
41: #include <sys/ioctl.h>
42: #include <net/if.h>
43: #include <netns/ns.h>
44: #include <netns/idp.h>
45: #include <signal.h>
46:
47: #include <syslog.h>
48: #include <stdio.h>
49: #include <errno.h>
50:
51: #include "pex.h"
52:
53: #define DEFAULTNET 2269
54: #define BUFLEN 1024
55: #define BFSPEXClientType 2
56: #define BFSClearinghouseSocket 20
57: #define BFSClearinghouseProgram 2
58: #define BFSClearinghouseVersion 2
59: #define BFSAuthenticationSocket 21
60: #define BFSAuthenticationProgram 14
61: #define BFSAuthenticationVersion 2
62:
63: extern char *ns_ntoa();
64: int authlookup= 0;
65:
66: static int s;
67: static int rnum = 1; /* PEX transaction ID */
68: static union {
69: u_long c_long;
70: u_short c_short[2];
71: } converter;
72:
73: struct xnsifdata {
74: struct sockaddr_ns myaddr;
75: struct sockaddr_ns bcstaddr;
76: };
77:
78: sendrequest(s,who,prognum,vernum)
79: int s;
80: struct sockaddr_ns *who;
81: u_long prognum;
82: u_short vernum;
83: {
84: struct pex *pex;
85: struct CourierData {
86: u_short courierlow;
87: u_short courierhigh;
88: u_short couriermsgtype;
89: u_short tid;
90: u_short program[2];
91: u_short version;
92: u_short procval;
93: } *cd;
94: char buf[576];
95: int len;
96:
97: pex = (struct pex *)&buf[0];
98: cd = (struct CourierData *)&buf[/* sizeof struct pex */ 6 ];
99:
100: pex->ph_idh = 0;
101: pex->ph_idl = htons(rnum++);
102: pex->ph_client = htons(BFSPEXClientType);
103:
104: cd->courierlow = cd->courierhigh = htons(3);
105: cd->couriermsgtype = cd->tid = 0;
106: converter.c_long = htonl(prognum);
107: cd->program[0] = converter.c_short[0];
108: cd->program[1] = converter.c_short[1];
109: cd->version = htons(vernum);
110: cd->procval = 0;
111:
112: len = sizeof (*cd) + /* sizeof(*pex) */ 6;
113: if ( sendto(s, (char*)buf, len, 0, who, sizeof (*who)) < 0) {
114: perror("sendto");
115: }
116: }
117:
118: #define NUMIFS 20
119: main(argc, argv)
120: int argc;
121: char *argv[];
122: {
123: struct ns_addr * daddr;
124: struct xnsifdata baddrlist[NUMIFS];
125: extern struct ns_addr *getXNSaddr();
126: extern FILE *outfile; int i, numif;
127:
128: outfile = stdout;
129:
130: numif = localbcst(baddrlist);
131: if (argc <= 1)
132: for (i = 0; i < numif; i++)
133: bfs(baddrlist[i]);
134: else for (i=1; i < argc; i++)
135: if ( strcmp(argv[i], "-a") == 0 ) {
136: authlookup++;
137: if (argc == 2) {
138: for (i = 0; i < numif; i++)
139: bfs(baddrlist[i]);
140: }
141: } else if ((daddr = getXNSaddr(argv[i])) != (struct ns_addr *) NULL) {
142: baddrlist[i].bcstaddr.sns_family = AF_NS;
143: if (daddr->x_host.s_host[0] == 0 &&
144: daddr->x_host.s_host[1] == 0 &&
145: daddr->x_host.s_host[2] == 0) {
146: daddr->x_host.s_host[0] = 0xFFFF;
147: daddr->x_host.s_host[1] = 0xFFFF;
148: daddr->x_host.s_host[2] = 0xFFFF;
149: }
150: baddrlist[i-1].bcstaddr.sns_addr = *daddr;
151: baddrlist[i-1].myaddr.sns_family = AF_NS;
152: bfs(baddrlist[i-1]);
153: }
154:
155: exit(0);
156: }
157:
158:
159:
160: bfs(ifdata)
161: struct xnsifdata ifdata;
162: {
163: struct sockaddr_ns me, you, who;
164: struct idp *idp;
165: struct pex *pex;
166: u_short *data;
167: struct ns_addr *srvr;
168: char buf[576];
169: int yoursize;
170: int m,n,clienttype;
171: int bytesReceived;
172: static int on = 1;
173: int mask;
174: struct timeval tval;
175: u_long prognum;
176: u_short vernum;
177:
178: if ((s = socket(AF_NS, SOCK_DGRAM, 0)) < 0) {
179: perror("socket");
180: exit(1);
181: }
182:
183: idp = (struct idp *)&buf[0];
184: pex = (struct pex *) &buf[ sizeof (struct idp)];
185: data = (u_short *) &buf[sizeof (struct idp) + /*sizeof (struct pex)*/ 6];
186:
187: me = ifdata.myaddr;
188: me.sns_port = htons(getpid()%1000+3000); /* so we don't have to be root */
189: if (bind(s, &me, sizeof (me)) < 0 ) {
190: perror("bind:");
191: exit(1);
192: }
193: if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) {
194: perror("setsockopt SEE HEADERS:");
195: exit(1);
196: }
197: idp->idp_pt = NSPROTO_PE;
198: if (setsockopt(s, 0, SO_DEFAULT_HEADERS, idp, sizeof(struct idp))) {
199: perror("setsockopt SET HEADER:");
200: exit(1);
201: }
202: if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
203: perror("setsockopt SO_BROADCAST:");
204: exit(1);
205: }
206:
207: who = ifdata.bcstaddr;
208: if (authlookup) {
209: who.sns_port = htons(BFSAuthenticationSocket);
210: prognum= BFSAuthenticationProgram;
211: vernum= BFSAuthenticationVersion;
212: } else {
213: who.sns_port = htons(BFSClearinghouseSocket);
214: prognum= BFSClearinghouseProgram;
215: vernum= BFSClearinghouseVersion;
216: }
217:
218: sendrequest(s,&who, prognum, vernum);
219: tval.tv_sec = 3;
220: tval.tv_usec = 0;
221: mask = 1<<s;
222: while ((select(20, &mask, 0, 0, &tval) > 0)
223: && (mask & 1<<s) ) {
224: fflush(stdout);
225:
226: yoursize = sizeof (you);
227: if ((n = recvfrom(s, (char *) buf, sizeof(buf), 0, &you, &yoursize)) < 0) {
228: extern int errno;
229:
230: if (errno != EINTR)
231: perror("rcvfrom:");
232: continue;
233: }
234: tval.tv_sec = 3;
235: tval.tv_usec = 0;
236: mask = 1<<s;
237:
238: if ( idp->idp_pt != NSPROTO_PE ) {
239: fprintf(stderr,"idp_pt = %d ?\n", idp->idp_pt);
240: continue;
241: }
242:
243: converter.c_short[0] = pex->ph_idh;
244: converter.c_short[1] = pex->ph_idl;
245: m = htonl(converter.c_long);
246: clienttype = ntohs(pex->ph_client);
247: bytesReceived = n - sizeof (struct idp) - /*sizeof (struct pex)*/ 6;
248: if ( clienttype != BFSPEXClientType)
249: continue;
250:
251: /* got a BFS reply packet, figure out what it is */
252: /* figure out size of packet */
253: if (ntohs(data[2]) == 2 /* result */ ) {
254: srvr = (struct ns_addr *)&data[6];
255: }
256:
257: printdomains(you.sns_addr);
258:
259: } /* listen for more */
260: close(s);
261: }
262:
263:
264: /*
265: * return the broadcast address (including network number) of the local network.
266: * We consider only broadcast nets, though a reasonable extension would be to
267: * send a point-to-point BFS to the host at the other end of a p-to-p link.
268: */
269: localbcst(results)
270: struct xnsifdata results[];
271: {
272: int s, n, numinterfaces, numxnsifs;
273: struct ifconf ifc;
274: char buf[sizeof(struct ifreq) * (NUMIFS-1)]; /* array of structures */
275: struct ifreq *ifr;
276: extern char *malloc();
277:
278: if ((s = socket(AF_NS, SOCK_DGRAM, 0)) < 0) {
279: perror("socket:");
280: exit(1);
281: }
282: ifc.ifc_len = sizeof (buf);
283: ifc.ifc_buf = buf;
284: if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
285: perror("ioctl SIOCGIFCONF:");
286: numinterfaces = 0;
287: } else
288: numinterfaces = ifc.ifc_len / sizeof (struct ifreq);
289: for (n = 0, ifr = ifc.ifc_req, numxnsifs = 0;
290: n < numinterfaces && numxnsifs < NUMIFS-1;
291: n++, ifr++) {
292: /* no one cares about software loopback interfaces */
293: /* we don't care about non-XNS addressess either */
294: if (strncmp(ifr->ifr_name,"lo", 2)==0 ||
295: ifr->ifr_addr.sa_family != AF_NS)
296: continue;
297: results[numxnsifs].myaddr =
298: *(struct sockaddr_ns *) &ifr->ifr_addr;
299: /* get IF flags */
300: if (ioctl(s, SIOCGIFFLAGS, (char *)ifr) < 0) {
301: perror("ioctl SIOCGIFFLAGS:");
302: continue;
303: }
304: if ((ifr->ifr_flags & IFF_UP) == 0 ||
305: (ifr->ifr_flags & IFF_BROADCAST) == 0)
306: continue;
307: /* get the broadcast address */
308: if (ioctl(s, SIOCGIFBRDADDR, (char *)ifr) < 0) {
309: perror("ioctl SIOCGIFBRDADDR:");
310: continue;
311: }
312: bcopy( &ifr->ifr_broadaddr,
313: &results[numxnsifs++].bcstaddr,
314: sizeof(struct sockaddr_ns) );
315: }
316: close(s);
317: return numxnsifs;
318: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.