# 2.11BSD#431 - /usr/src/usr.sbin/ntp/ntp_sock.c

##### Functions

    create_sockets    X
    main              X

##### Variables

    addrs             X
    nintf             X

##### Macros

    MAX_INTF          X

       1: #ifndef lint
       2: static char *RCSid = "$Source: /usr/users/louie/ntp/RCS/ntp_sock.c,v $ $Revision: 3.4.1.3 $ $Date: 89/05/18 18:28:20 $";
       3: #endif
       4:
       5: /*
       6:  * $Log:	ntp_sock.c,v $
       7:  * Revision 3.4.1.3  89/05/18  18:28:20  louie
       8:  * In ntp_sock.c, change the order that the bind() call is done for each socket.
       9:  * It turns out that if you have the Multicast code installed, incoming packets
      10:  * will be delived to the *first* socket that matches.  It also turns out that
      11:  * when binding sockets, the first one bound is the last on checked, so we want
      12:  * to bind the wildcard socket first.
      13:  *
      14:  * Revision 3.4.1.2  89/04/07  19:07:46  louie
      15:  * Deleted unused variables in ntp_sock.c
      16:  *
      17:  * Revision 3.4.1.1  89/03/22  18:31:20  louie
      18:  * patch3: Use new RCS headers.
      19:  *
      20:  * Revision 3.4  89/03/17  18:37:09  louie
      21:  * Latest test release.
      22:  *
      23:  * Revision 3.3  89/03/15  14:19:53  louie
      24:  * New baseline for next release.
      25:  *
      26:  * Revision 3.2.1.1  89/03/10  11:30:41  louie
      27:  * 1
      28:  *
      29:  * Revision 3.2  89/03/07  18:26:26  louie
      30:  * New version of UNIX NTP daemon based on the 6 March 1989 draft of the new
      31:  * NTP protocol specification.  This version has a bunch of bugs fixes and
      32:  * new algorithms which were discussed on the NTP mailing list over the past
      33:  * few weeks.
      34:  *
      35:  * Revision 3.1.1.1  89/02/15  08:56:28  louie
      36:  * *** empty log message ***
      37:  *
      38:  *
      39:  * Revision 3.1  89/01/30  14:43:12  louie
      40:  * Second UNIX NTP test release.
      41:  *
      42:  * Revision 3.0  88/12/12  16:00:15  louie
      43:  * Test release of new UNIX NTP software.  This version should conform to the
      44:  * revised NTP protocol specification.
      45:  *
      46:  */
      47:
      48: #include <sys/types.h>
      49: #include <sys/param.h>
      50: #include <sys/ioctl.h>
      51: #include <sys/file.h>
      52: #include <sys/socket.h>
      53: #include <netinet/in.h>
      54: #include <net/if.h>
      55: #include <errno.h>
      56: #include <syslog.h>
      57: #include <stdio.h>
      58: #include "ntp.h"
      59:
      60: #define MAX_INTF    10
      61: struct intf addrs[MAX_INTF];
      62: int nintf;
      63:
      64: #ifdef  TEST
      65: extern int errno;
      66:
      67: main() {
      68:     int i, cc, val;
      69:     char foo[10];
      70:
      71:     syslog(LOG_ERR, "ifconfig test");
      72:     create_sockets(htons(43242));
      73:     for (i = 0; i < nintf; i++) {
      74:         printf("%d: %s fd %d  addr %s  mask %x ",
      75:                i, addrs[i].name, addrs[i].fd,
      76:                inet_ntoa(addrs[i].sin.sin_addr.s_addr),
      77:                ntohl(addrs[i].mask.sin_addr.s_addr));
      78:         cc = sizeof(val);
      79:         if (getsockopt(addrs[0].fd, SOL_SOCKET, SO_BROADCAST,
      80:                    (char*)&val, &cc)) {
      81:             perror("getsockopt");
      82:             exit(1);
      83:         }
      84:         printf("BCAST opt %d", val);
      85:         cc = sizeof(val);
      86:         if (getsockopt(addrs[0].fd, SOL_SOCKET, SO_RCVBUF,
      87:                    (char*)&val, &cc)) {
      88:             perror("getsockopt");
      89:             exit(1);
      90:         }
      91:         printf("sockbuf size = %d ", val);
      92:         putchar('\n');
      93:     }
      94:
      95:     for (i=0; i < nintf; i++) {
      96:         fprintf(stderr, "Read fd %d.. ", addrs[i].fd);
      97:         cc = read(addrs[i].fd, foo, 10);
      98:         fprintf(stderr, " returns %d ", cc);
      99:         perror("read errno");
     100:     }
     101: }
     102: #endif
     103:
     104: #ifndef SIOCGIFCONF
     105: /*
     106:  *  If we can't determine the interface configuration, just listen with one
     107:  *  socket at the INADDR_ANY address.
     108:  */
     109: create_sockets(port)
     110:     unsigned int port;
     111: {
     112:     addrs[0].sin.sin_family = AF_INET;
     113:     addrs[0].sin.sin_port = 0;
     114:     addrs[0].sin.sin_addr.s_addr = INADDR_ANY;
     115:     addrs[0].sin.sin_mask.s_addr = htonl(~0);
     116:     addrs[0].name = "wildcard";
     117:
     118:     if ((addrs[0].fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
     119:         syslog(LOG_ERR, "socket() failed: %m");
     120: #ifdef  TEST
     121:         perror( "socket() failed");
     122: #endif
     123:         exit(1);
     124:         /*NOTREACHED*/
     125:     }
     126:
     127:     if (fcntl(addrs[i].fd, F_SETFL, FNDELAY) < 0) {
     128:         syslog(LOG_ERR, "fcntl(FNDELAY) fails: %m");
     129: #ifdef  TEST
     130:         perror("fcntl(FNDELAY) fails");
     131: #endif
     132:         exit(1);
     133:         /*NOTREACHED*/
     134:     }
     135:     addrs[0].sin.sin_family = AF_INET;
     136:     addrs[0].sin.sin_port = port;
     137:     addrs[0].if_flags = 0;
     138:     if (bind(addrs[0].fd, (struct sockaddr *)&addrs[0].sin,
     139:          sizeof(addrs[0].sin)) < 0) {
     140:         syslog(LOG_ERR, "bind() fails: %m");
     141: #ifdef  TEST
     142:         perror("bind fails\n");
     143: #endif
     144:         exit(1);
     145:     }
     146:     nintf = 1;
     147:     return nintf;
     148: }
     149: #else
     150: /*
     151:  *  Grab interface configuration, and create a socket for each interface
     152:  *  address.
     153:  */
     154: create_sockets(port)
     155:     unsigned int port;
     156: {
     157:     char    buf[1024];
     158:     struct  ifconf  ifc;
     159:     struct  ifreq   ifreq, *ifr;
     160:     int on = 1, off = 0;
     161:     int n, i, vs;
     162:     extern char *malloc();
     163:
     164:     /*
     165: 	 * create pseudo-interface with wildcard address
     166: 	 */
     167:     addrs[nintf].sin.sin_family = AF_INET;
     168:     addrs[nintf].sin.sin_port = 0;
     169:     addrs[nintf].sin.sin_addr.s_addr = INADDR_ANY;
     170:     addrs[nintf].name = "wild";
     171:     addrs[nintf].mask.sin_addr.s_addr = htonl(~0);
     172:
     173:     nintf = 1;
     174:
     175:     if ((vs = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
     176:         syslog(LOG_ERR, "vs=socket(AF_INET, SOCK_DGRAM) %m");
     177: #ifdef  TEST
     178:         perror("vs=socket(AF_INET, SOCK_DGRAM)");
     179: #endif
     180:         exit(1);
     181:     }
     182:     ifc.ifc_len = sizeof(buf);
     183:     ifc.ifc_buf = buf;
     184:     if (ioctl(vs, SIOCGIFCONF, (char *)&ifc) < 0) {
     185:         syslog(LOG_ERR, "get interface configuration: %m");
     186: #ifdef  TEST
     187:         perror("ioctl(SIOCGIFCONF) fails");
     188: #endif
     189:         exit(1);
     190:     }
     191:     n = ifc.ifc_len/sizeof(struct ifreq);
     192:
     193:     for (ifr = ifc.ifc_req; n > 0; n--, ifr++) {
     194:         if (ifr->ifr_addr.sa_family != AF_INET)
     195:             continue;
     196:         ifreq = *ifr;
     197:         if (ioctl(vs, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
     198:             syslog(LOG_ERR, "get interface flags: %m");
     199: #ifdef  TEST
     200:             perror("SIOCGIFFFLAGS fails");
     201: #endif
     202:             continue;
     203:         }
     204:         if ((ifreq.ifr_flags & IFF_UP) == 0)
     205:             continue;
     206:         addrs[nintf].if_flags = ifreq.ifr_flags;
     207:
     208:         if (ioctl(vs, SIOCGIFADDR, (char *)&ifreq) < 0) {
     209:             syslog(LOG_ERR, "get interface addr: %m");
     210: #ifdef  TEST
     211:             perror("SIOCGIFADDR fails");
     212: #endif
     213:             continue;
     214:         }
     215:         if ((addrs[nintf].name = malloc(strlen(ifreq.ifr_name)+1))
     216:                 == NULL) {
     217:             syslog(LOG_ERR, "malloc failed");
     218:             exit(1);
     219:         }
     220:         strcpy(addrs[nintf].name, ifreq.ifr_name);
     221:         addrs[nintf].sin = *(struct sockaddr_in *)&ifreq.ifr_addr;
     222:
     223: #ifdef SIOCGIFBRDADDR
     224:         if (addrs[nintf].if_flags & IFF_BROADCAST) {
     225:             if (ioctl(vs, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
     226:                 syslog(LOG_ERR, "SIOCGIFBRDADDR fails");
     227: #ifdef  TEST
     228:                 perror("SIOCGIFBRDADDR fails");
     229: #endif
     230:                 exit(1);
     231:             }
     232: #ifndef SUN_3_3
     233:             addrs[nintf].bcast =
     234:                 *(struct sockaddr_in *)&ifreq.ifr_broadaddr;
     235: #else
     236:             addrs[nintf].bcast =
     237:                 *(struct sockaddr_in *)&ifreq.ifr_addr;
     238: #endif
     239:         }
     240: #endif /* SIOCGIFBRDADDR */
     241: #ifdef SIOCGIFNETMASK
     242:         if (ioctl(vs, SIOCGIFNETMASK, (char *)&ifreq) < 0) {
     243:             syslog(LOG_ERR, "SIOCGIFNETMASK fails");
     244: #ifdef  TEST
     245:             perror("SIOCGIFNETMASK fails");
     246: #endif
     247:             exit(1);
     248:         }
     249:         addrs[nintf].mask = *(struct sockaddr_in *)&ifreq.ifr_addr;
     250: #endif /* SIOCGIFNETMASK */
     251:
     252:         /*
     253: 		 * look for an already existing source interface address.  If
     254: 		 * the machine has multiple point to point interfaces, then
     255: 		 * the local address may appear more than once.
     256: 		 */
     257:         for (i=0; i < nintf; i++)
     258:             if (addrs[i].sin.sin_addr.s_addr ==
     259:                 addrs[nintf].sin.sin_addr.s_addr) {
     260: #ifdef TEST
     261:                 printf("dup interface address %s on %s\n",
     262:                     inet_ntoa(addrs[nintf].sin.sin_addr.s_addr),
     263:                     ifreq.ifr_name);
     264: #endif
     265:                 goto next;
     266:             }
     267:         nintf++;
     268:        next:;
     269:     }
     270:     close(vs);
     271:
     272:     for (i = 0; i < nintf; i++) {
     273:         /* create a datagram (UDP) socket */
     274:         if ((addrs[i].fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
     275:             syslog(LOG_ERR, "socket() failed: %m");
     276: #ifdef  TEST
     277:             perror("socket(AF_INET, SOCK_DGRAM) fails");
     278: #endif
     279:             exit(1);
     280:             /*NOTREACHED*/
     281:         }
     282:
     283:         /* set SO_REUSEADDR since we will be binding the same port
     284: 		   number on each interface */
     285:         if (setsockopt(addrs[i].fd, SOL_SOCKET, SO_REUSEADDR,
     286:                   (char *)&on, sizeof(on))) {
     287: #ifdef  TEST
     288:             perror("setsockopt SO_REUSEADDR on");
     289: #endif
     290:             syslog(LOG_ERR, "setsockopt SO_REUSEADDR on fails: %m");
     291:         }
     292:
     293:         /*
     294: 		 * set non-blocking I/O on the descriptor
     295: 		 */
     296:         if (fcntl(addrs[i].fd, F_SETFL, FNDELAY) < 0) {
     297:             syslog(LOG_ERR, "fcntl(FNDELAY) fails: %m");
     298: #ifdef  TEST
     299:             perror("fcntl(F_SETFL, FNDELAY) fails");
     300: #endif
     301:             exit(1);
     302:             /*NOTREACHED*/
     303:         }
     304:
     305:         /*
     306: 		 * finally, bind the local address address.
     307: 		 */
     308:         addrs[i].sin.sin_family = AF_INET;
     309:         addrs[i].sin.sin_port = port;
     310:         if (bind(addrs[i].fd, (struct sockaddr *)&addrs[i].sin,
     311:              sizeof(addrs[i].sin)) < 0) {
     312:             syslog(LOG_ERR, "bind() fails: %m");
     313: #ifdef  TEST
     314:             perror("bind fails");
     315: #endif
     316:             exit(1);
     317:         }
     318:
     319:         /*
     320: 		 *  Turn off the SO_REUSEADDR socket option.  It apparently
     321: 		 *  causes heartburn on systems with multicast IP installed.
     322: 		 *  On normal systems it only gets looked at when the address
     323: 		 *  is being bound anyway..
     324: 		 */
     325:         if (setsockopt(addrs[i].fd, SOL_SOCKET, SO_REUSEADDR,
     326:                    (char *)&off, sizeof(off))) {
     327:             syslog(LOG_ERR, "setsockopt SO_REUSEADDR off fails: %m");
     328: #ifdef  TEST
     329:             perror("setsockopt SO_REUSEADDR off");
     330: #endif
     331:         }
     332:
     333: #ifdef SO_BROADCAST
     334:         /* if this interface can support broadcast, set SO_BROADCAST */
     335:         if (addrs[i].if_flags & IFF_BROADCAST) {
     336:             if (setsockopt(addrs[i].fd, SOL_SOCKET, SO_BROADCAST,
     337:                        (char *)&on, sizeof(on))) {
     338:                 syslog(LOG_ERR, "setsockopt(SO_BROADCAST): %m");
     339: #ifdef  TEST
     340:                 perror("setsockopt(SO_BROADCAST) on");
     341: #endif
     342:             }
     343:         }
     344: #endif /* SO_BROADCAST */
     345:     }
     346:     return nintf;
     347: }
     348:
     349: #endif

#### Defined functions

create_sockets defined in line 154; used 3 times

- in line 72
- in /usr/src/usr.sbin/ntp/ntpd.c line 315-317(2)

main defined in line 67; never used

#### Defined variables

RCSid defined in line 2; never used
addrs defined in line 61; used 119 times

- in line 75-79(5), 86, 96-97(2), 112-118(6), 127, 135-139(6), 167-171(5), 206, 215-224(4), 233-236(2), 249, 258-262(3), 274, 285, 296, 308-311(5), 325, 335-336(2)
- in /usr/src/usr.sbin/ntp/ntp_proto.c line 210, 254, 1239
- in /usr/src/usr.sbin/ntp/ntp_sock.c line 75-79(5), 86, 96-97(2), 112-118(6), 127, 135-139(6), 167-171(5), 206, 215-224(4), 233-236(2), 249, 258-262(3), 274, 285, 296, 308-311(5), 325, 335-336(2)
- in /usr/src/usr.sbin/ntp/ntpd.c line 339-350(9), 393-398(3), 808, 815-820(2), 835, 928, 1140, 1172, 1187

nintf defined in line 62; used 54 times

- in line 73, 95, 146-147(2), 167-173(6), 206, 215-224(4), 233-236(2), 249, 257-272(5), 346
- in /usr/src/usr.sbin/ntp/ntp_proto.c line 1238
- in /usr/src/usr.sbin/ntp/ntp_sock.c line 73, 95, 146-147(2), 167-173(6), 206, 215-224(4), 233-236(2), 249, 257-272(5), 346
- in /usr/src/usr.sbin/ntp/ntpd.c line 338, 392, 807-810(2), 927

#### Defined macros

MAX_INTF defined in line 60; used 1 times

- in line 61

Last modified: 1989-05-19 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1970 |