+ ip->ip_id = htons(ip_id++);
+
+ /*
+ * Route packet.
+ */
+ if (ro == 0) {
+ ro = &iproute;
+ bzero((caddr_t)ro, sizeof (*ro));
+ }
+ dst = &ro->ro_dst;
+ if (ro->ro_rt == 0) {
+ ro->ro_dst.sa_family = AF_INET;
+ ((struct sockaddr_in *)&ro->ro_dst)->sin_addr = ip->ip_dst;
+ /*
+ * If routing to interface only, short circuit routing lookup.
+ */
+ if (ro == &routetoif) {
+ /* check ifp is AF_INET??? */
+ ifp = if_ifonnetof(IN_NETOF(ip->ip_dst));
+ if (ifp == 0)
+ goto unreachable;
+ goto gotif;
+ }
+ rtalloc(ro);
+ }
+ if (ro->ro_rt == 0 || (ifp = ro->ro_rt->rt_ifp) == 0)
+ goto unreachable;
+ ro->ro_rt->rt_use++;
+ if (ro->ro_rt->rt_flags & RTF_GATEWAY)
+ dst = &ro->ro_rt->rt_gateway;
+gotif:
+ /*
+ * If source address not specified yet, use address
+ * of outgoing interface.
+ */
+ if (ip->ip_src.s_addr == 0)
+ ip->ip_src.s_addr =
+ ((struct sockaddr_in *)&ifp->if_addr)->sin_addr.s_addr;
+
+ /*
+ * Have interface for packet. Allow
+ * broadcasts only by authorized users.
+ */
+ if (!allowbroadcast && (ifp->if_flags & IFF_BROADCAST)) {
+ struct sockaddr_in *sin;
+
+ sin = (struct sockaddr_in *)&ifp->if_broadaddr;
+ if (sin->sin_addr.s_addr == ip->ip_dst.s_addr) {
+ error = EACCES;
+ goto bad;
+ }
+ }