Print this page
4823 don't open-code NSEC2MSEC and MSEC2NSEC


1481                 /* Check db_ref to make sure we can modify the packet. */
1482                 if (mp->b_datap->db_ref > 1) {
1483                         mblk_t  *mp1;
1484 
1485                         mp1 = copymsg(mp);
1486                         freemsg(mp);
1487                         if (!mp1) {
1488                                 BUMP_MIB(&ipst->ips_icmp_mib, icmpOutDrops);
1489                                 return (NULL);
1490                         }
1491                         mp = mp1;
1492                         ipha = (ipha_t *)mp->b_rptr;
1493                         icmph = (icmph_t *)&mp->b_rptr[ip_hdr_length];
1494                 }
1495                 icmph->icmph_type = ICMP_TIME_STAMP_REPLY;
1496                 tsp = (uint32_t *)&icmph[1];
1497                 tsp++;          /* Skip past 'originate time' */
1498                 /* Compute # of milliseconds since midnight */
1499                 gethrestime(&now);
1500                 ts = (now.tv_sec % (24 * 60 * 60)) * 1000 +
1501                     now.tv_nsec / (NANOSEC / MILLISEC);
1502                 *tsp++ = htonl(ts);     /* Lay in 'receive time' */
1503                 *tsp++ = htonl(ts);     /* Lay in 'send time' */
1504                 BUMP_MIB(&ipst->ips_icmp_mib, icmpOutTimestampReps);
1505                 icmp_send_reply_v4(mp, ipha, icmph, ira);
1506                 return (NULL);
1507 
1508         case ICMP_TIME_STAMP_REPLY:
1509                 BUMP_MIB(&ipst->ips_icmp_mib, icmpInTimestampReps);
1510                 break;
1511         case ICMP_INFO_REQUEST:
1512                 /* Per RFC 1122 3.2.2.7, ignore this. */
1513         case ICMP_INFO_REPLY:
1514                 break;
1515         case ICMP_ADDRESS_MASK_REQUEST:
1516                 if (ira->ira_flags & IRAF_MULTIBROADCAST) {
1517                         interested =
1518                             ipst->ips_ip_respond_to_address_mask_broadcast;
1519                 } else {
1520                         interested = B_TRUE;
1521                 }


9100                         switch (opt[IPOPT_POS_OV_FLG] & 0x0F) {
9101                         case IPOPT_TS_PRESPEC:
9102                         case IPOPT_TS_PRESPEC_RFC791:
9103                         case IPOPT_TS_TSANDADDR:
9104                                 /* Pick a reasonable addr on the outbound if */
9105                                 ASSERT(dst_ill != NULL);
9106                                 if (ip_select_source_v4(dst_ill, INADDR_ANY,
9107                                     dst, INADDR_ANY, ALL_ZONES, ipst, &ifaddr,
9108                                     NULL, NULL) != 0) {
9109                                         /* No source! Shouldn't happen */
9110                                         ifaddr = INADDR_ANY;
9111                                 }
9112                                 bcopy(&ifaddr, (char *)opt + off, IP_ADDR_LEN);
9113                                 opt[IPOPT_OFFSET] += IP_ADDR_LEN;
9114                                 /* FALLTHRU */
9115                         case IPOPT_TS_TSONLY:
9116                                 off = opt[IPOPT_OFFSET] - 1;
9117                                 /* Compute # of milliseconds since midnight */
9118                                 gethrestime(&now);
9119                                 ts = (now.tv_sec % (24 * 60 * 60)) * 1000 +
9120                                     now.tv_nsec / (NANOSEC / MILLISEC);
9121                                 bcopy(&ts, (char *)opt + off, IPOPT_TS_TIMELEN);
9122                                 opt[IPOPT_OFFSET] += IPOPT_TS_TIMELEN;
9123                                 break;
9124                         }
9125                         break;
9126                 }
9127         }
9128         return (B_TRUE);
9129 }
9130 
9131 /*
9132  * Call ill_frag_timeout to do garbage collection. ill_frag_timeout
9133  * returns 'true' if there are still fragments left on the queue, in
9134  * which case we restart the timer.
9135  */
9136 void
9137 ill_frag_timer(void *arg)
9138 {
9139         ill_t   *ill = (ill_t *)arg;
9140         boolean_t frag_pending;


9326                         off = opt[IPOPT_OFFSET] - 1;
9327                         switch (opt[IPOPT_POS_OV_FLG] & 0x0F) {
9328                         case IPOPT_TS_PRESPEC:
9329                         case IPOPT_TS_PRESPEC_RFC791:
9330                         case IPOPT_TS_TSANDADDR:
9331                                 /* Pick a reasonable addr on the outbound if */
9332                                 if (ip_select_source_v4(ill, INADDR_ANY,
9333                                     ipha->ipha_dst, INADDR_ANY, ALL_ZONES, ipst,
9334                                     &ifaddr, NULL, NULL) != 0) {
9335                                         /* No source! Shouldn't happen */
9336                                         ifaddr = INADDR_ANY;
9337                                 }
9338                                 bcopy(&ifaddr, (char *)opt + off, IP_ADDR_LEN);
9339                                 opt[IPOPT_OFFSET] += IP_ADDR_LEN;
9340                                 /* FALLTHRU */
9341                         case IPOPT_TS_TSONLY:
9342                                 off = opt[IPOPT_OFFSET] - 1;
9343                                 /* Compute # of milliseconds since midnight */
9344                                 gethrestime(&now);
9345                                 ts = (now.tv_sec % (24 * 60 * 60)) * 1000 +
9346                                     now.tv_nsec / (NANOSEC / MILLISEC);
9347                                 bcopy(&ts, (char *)opt + off, IPOPT_TS_TIMELEN);
9348                                 opt[IPOPT_OFFSET] += IPOPT_TS_TIMELEN;
9349                                 break;
9350                         }
9351                         break;
9352                 }
9353         }
9354         return (B_TRUE);
9355 
9356 bad_src_route:
9357         /* make sure we clear any indication of a hardware checksum */
9358         DB_CKSUMFLAGS(mp) = 0;
9359         ip_drop_input("ICMP_SOURCE_ROUTE_FAILED", mp, ill);
9360         icmp_unreachable(mp, ICMP_SOURCE_ROUTE_FAILED, ira);
9361         return (B_FALSE);
9362 
9363 }
9364 
9365 /*
9366  * Process IP options in an inbound packet.  Always returns the nexthop.


12008                                 off = (opt[IPOPT_POS_OV_FLG] >> 4) + 1;
12009                                 opt[IPOPT_POS_OV_FLG] = (uint8_t)
12010                                     (opt[IPOPT_POS_OV_FLG] & 0x0F) |
12011                                     (off << 4);
12012                                 break;
12013                         }
12014                         off = opt[IPOPT_OFFSET] - 1;
12015                         switch (opt[IPOPT_POS_OV_FLG] & 0x0F) {
12016                         case IPOPT_TS_PRESPEC:
12017                         case IPOPT_TS_PRESPEC_RFC791:
12018                         case IPOPT_TS_TSANDADDR:
12019                                 dst = htonl(INADDR_LOOPBACK);
12020                                 bcopy(&dst, (char *)opt + off, IP_ADDR_LEN);
12021                                 opt[IPOPT_OFFSET] += IP_ADDR_LEN;
12022                                 /* FALLTHRU */
12023                         case IPOPT_TS_TSONLY:
12024                                 off = opt[IPOPT_OFFSET] - 1;
12025                                 /* Compute # of milliseconds since midnight */
12026                                 gethrestime(&now);
12027                                 ts = (now.tv_sec % (24 * 60 * 60)) * 1000 +
12028                                     now.tv_nsec / (NANOSEC / MILLISEC);
12029                                 bcopy(&ts, (char *)opt + off, IPOPT_TS_TIMELEN);
12030                                 opt[IPOPT_OFFSET] += IPOPT_TS_TIMELEN;
12031                                 break;
12032                         }
12033                         break;
12034                 }
12035         }
12036 }
12037 
12038 /*
12039  * Prepend an M_DATA fastpath header, and if none present prepend a
12040  * DL_UNITDATA_REQ. Frees the mblk on failure.
12041  *
12042  * nce_dlur_mp and nce_fp_mp can not disappear once they have been set.
12043  * If there is a change to them, the nce will be deleted (condemned) and
12044  * a new nce_t will be created when packets are sent. Thus we need no locks
12045  * to access those fields.
12046  *
12047  * We preserve b_band to support IPQoS. If a DL_UNITDATA_REQ is prepended
12048  * we place b_band in dl_priority.dl_max.




1481                 /* Check db_ref to make sure we can modify the packet. */
1482                 if (mp->b_datap->db_ref > 1) {
1483                         mblk_t  *mp1;
1484 
1485                         mp1 = copymsg(mp);
1486                         freemsg(mp);
1487                         if (!mp1) {
1488                                 BUMP_MIB(&ipst->ips_icmp_mib, icmpOutDrops);
1489                                 return (NULL);
1490                         }
1491                         mp = mp1;
1492                         ipha = (ipha_t *)mp->b_rptr;
1493                         icmph = (icmph_t *)&mp->b_rptr[ip_hdr_length];
1494                 }
1495                 icmph->icmph_type = ICMP_TIME_STAMP_REPLY;
1496                 tsp = (uint32_t *)&icmph[1];
1497                 tsp++;          /* Skip past 'originate time' */
1498                 /* Compute # of milliseconds since midnight */
1499                 gethrestime(&now);
1500                 ts = (now.tv_sec % (24 * 60 * 60)) * 1000 +
1501                     NSEC2MSEC(now.tv_nsec);
1502                 *tsp++ = htonl(ts);     /* Lay in 'receive time' */
1503                 *tsp++ = htonl(ts);     /* Lay in 'send time' */
1504                 BUMP_MIB(&ipst->ips_icmp_mib, icmpOutTimestampReps);
1505                 icmp_send_reply_v4(mp, ipha, icmph, ira);
1506                 return (NULL);
1507 
1508         case ICMP_TIME_STAMP_REPLY:
1509                 BUMP_MIB(&ipst->ips_icmp_mib, icmpInTimestampReps);
1510                 break;
1511         case ICMP_INFO_REQUEST:
1512                 /* Per RFC 1122 3.2.2.7, ignore this. */
1513         case ICMP_INFO_REPLY:
1514                 break;
1515         case ICMP_ADDRESS_MASK_REQUEST:
1516                 if (ira->ira_flags & IRAF_MULTIBROADCAST) {
1517                         interested =
1518                             ipst->ips_ip_respond_to_address_mask_broadcast;
1519                 } else {
1520                         interested = B_TRUE;
1521                 }


9100                         switch (opt[IPOPT_POS_OV_FLG] & 0x0F) {
9101                         case IPOPT_TS_PRESPEC:
9102                         case IPOPT_TS_PRESPEC_RFC791:
9103                         case IPOPT_TS_TSANDADDR:
9104                                 /* Pick a reasonable addr on the outbound if */
9105                                 ASSERT(dst_ill != NULL);
9106                                 if (ip_select_source_v4(dst_ill, INADDR_ANY,
9107                                     dst, INADDR_ANY, ALL_ZONES, ipst, &ifaddr,
9108                                     NULL, NULL) != 0) {
9109                                         /* No source! Shouldn't happen */
9110                                         ifaddr = INADDR_ANY;
9111                                 }
9112                                 bcopy(&ifaddr, (char *)opt + off, IP_ADDR_LEN);
9113                                 opt[IPOPT_OFFSET] += IP_ADDR_LEN;
9114                                 /* FALLTHRU */
9115                         case IPOPT_TS_TSONLY:
9116                                 off = opt[IPOPT_OFFSET] - 1;
9117                                 /* Compute # of milliseconds since midnight */
9118                                 gethrestime(&now);
9119                                 ts = (now.tv_sec % (24 * 60 * 60)) * 1000 +
9120                                     NSEC2MSEC(now.tv_nsec);
9121                                 bcopy(&ts, (char *)opt + off, IPOPT_TS_TIMELEN);
9122                                 opt[IPOPT_OFFSET] += IPOPT_TS_TIMELEN;
9123                                 break;
9124                         }
9125                         break;
9126                 }
9127         }
9128         return (B_TRUE);
9129 }
9130 
9131 /*
9132  * Call ill_frag_timeout to do garbage collection. ill_frag_timeout
9133  * returns 'true' if there are still fragments left on the queue, in
9134  * which case we restart the timer.
9135  */
9136 void
9137 ill_frag_timer(void *arg)
9138 {
9139         ill_t   *ill = (ill_t *)arg;
9140         boolean_t frag_pending;


9326                         off = opt[IPOPT_OFFSET] - 1;
9327                         switch (opt[IPOPT_POS_OV_FLG] & 0x0F) {
9328                         case IPOPT_TS_PRESPEC:
9329                         case IPOPT_TS_PRESPEC_RFC791:
9330                         case IPOPT_TS_TSANDADDR:
9331                                 /* Pick a reasonable addr on the outbound if */
9332                                 if (ip_select_source_v4(ill, INADDR_ANY,
9333                                     ipha->ipha_dst, INADDR_ANY, ALL_ZONES, ipst,
9334                                     &ifaddr, NULL, NULL) != 0) {
9335                                         /* No source! Shouldn't happen */
9336                                         ifaddr = INADDR_ANY;
9337                                 }
9338                                 bcopy(&ifaddr, (char *)opt + off, IP_ADDR_LEN);
9339                                 opt[IPOPT_OFFSET] += IP_ADDR_LEN;
9340                                 /* FALLTHRU */
9341                         case IPOPT_TS_TSONLY:
9342                                 off = opt[IPOPT_OFFSET] - 1;
9343                                 /* Compute # of milliseconds since midnight */
9344                                 gethrestime(&now);
9345                                 ts = (now.tv_sec % (24 * 60 * 60)) * 1000 +
9346                                     NSEC2MSEC(now.tv_nsec);
9347                                 bcopy(&ts, (char *)opt + off, IPOPT_TS_TIMELEN);
9348                                 opt[IPOPT_OFFSET] += IPOPT_TS_TIMELEN;
9349                                 break;
9350                         }
9351                         break;
9352                 }
9353         }
9354         return (B_TRUE);
9355 
9356 bad_src_route:
9357         /* make sure we clear any indication of a hardware checksum */
9358         DB_CKSUMFLAGS(mp) = 0;
9359         ip_drop_input("ICMP_SOURCE_ROUTE_FAILED", mp, ill);
9360         icmp_unreachable(mp, ICMP_SOURCE_ROUTE_FAILED, ira);
9361         return (B_FALSE);
9362 
9363 }
9364 
9365 /*
9366  * Process IP options in an inbound packet.  Always returns the nexthop.


12008                                 off = (opt[IPOPT_POS_OV_FLG] >> 4) + 1;
12009                                 opt[IPOPT_POS_OV_FLG] = (uint8_t)
12010                                     (opt[IPOPT_POS_OV_FLG] & 0x0F) |
12011                                     (off << 4);
12012                                 break;
12013                         }
12014                         off = opt[IPOPT_OFFSET] - 1;
12015                         switch (opt[IPOPT_POS_OV_FLG] & 0x0F) {
12016                         case IPOPT_TS_PRESPEC:
12017                         case IPOPT_TS_PRESPEC_RFC791:
12018                         case IPOPT_TS_TSANDADDR:
12019                                 dst = htonl(INADDR_LOOPBACK);
12020                                 bcopy(&dst, (char *)opt + off, IP_ADDR_LEN);
12021                                 opt[IPOPT_OFFSET] += IP_ADDR_LEN;
12022                                 /* FALLTHRU */
12023                         case IPOPT_TS_TSONLY:
12024                                 off = opt[IPOPT_OFFSET] - 1;
12025                                 /* Compute # of milliseconds since midnight */
12026                                 gethrestime(&now);
12027                                 ts = (now.tv_sec % (24 * 60 * 60)) * 1000 +
12028                                     NSEC2MSEC(now.tv_nsec);
12029                                 bcopy(&ts, (char *)opt + off, IPOPT_TS_TIMELEN);
12030                                 opt[IPOPT_OFFSET] += IPOPT_TS_TIMELEN;
12031                                 break;
12032                         }
12033                         break;
12034                 }
12035         }
12036 }
12037 
12038 /*
12039  * Prepend an M_DATA fastpath header, and if none present prepend a
12040  * DL_UNITDATA_REQ. Frees the mblk on failure.
12041  *
12042  * nce_dlur_mp and nce_fp_mp can not disappear once they have been set.
12043  * If there is a change to them, the nce will be deleted (condemned) and
12044  * a new nce_t will be created when packets are sent. Thus we need no locks
12045  * to access those fields.
12046  *
12047  * We preserve b_band to support IPQoS. If a DL_UNITDATA_REQ is prepended
12048  * we place b_band in dl_priority.dl_max.