- p = (struct ip *)((int)mp + mp->m_off); /* -> ip header */
- hlen = sizeof(struct ip); /* header length */
-
- /* fill in unspecified fields and byte swap others */
-
- p->ip_v = IPVERSION;
- p->ip_hl = hlen >> 2;
- p->ip_off = 0 | (p->ip_off & ip_df);
- p->ip_ttl = MAXTTL;
- p->ip_id = netcb.n_ip_cnt++;
-
- if (p->ip_len > MTU) { /* must fragment */
- if (p->ip_off & ip_df)
- return(FALSE);
- max = MTU - hlen; /* maximum data length in fragment */
- len = p->ip_len - hlen; /* data length */
- off = 0; /* fragment offset */
- m = mp;
-
- while (len > 0) {
-
- /* correct the header */
-
- p->ip_off |= off >> 3;
-
- /* find the end of the fragment */
-
- i = -hlen;
- while (m != NULL) {
- i += m->m_len;
- if (i > max)
- break;
- n = m;
- m = m->m_next;
- }
-
- if (i < max || m == NULL) { /* last fragment */
- p->ip_off = p->ip_off & ~ip_mf;
- p->ip_len = i + hlen;
- break;
-
- } else { /* more fragments */
-
- /* allocate header mbuf for next fragment */
-
- if ((mm = m_get(1)) == NULL) /* no more bufs */
- return(FALSE);
-
- p->ip_off |= ip_mf;
-
- /* terminate fragment at 8 byte boundary (round down) */
-
- i -= m->m_len;
- rnd = i & ~7; /* fragment length */
- adj = i - rnd; /* leftover in mbuf */
- p->ip_len = rnd + hlen;
-
- /* setup header for next fragment and
- append remaining fragment data */
-
- n->m_next = NULL;
- mm->m_next = m;
- m = mm;
- m->m_off = MSIZE - hlen - adj;
- m->m_len = hlen + adj;
-
- /* copy old header to new */
-
- bcopy(p, (caddr_t)((int)m + m->m_off), hlen);
-
- /* copy leftover data from previous frag */
-
- if (adj) {
- n->m_len -= adj;
- bcopy((caddr_t)((int)n + n->m_len + n->m_off),
- (caddr_t)((int)m + m->m_off + hlen), adj);
- }
- }
+ if (opt) /* XXX */
+ (void) m_free(opt); /* XXX */
+ /*
+ * Fill in IP header.
+ */
+ ip->ip_v = IPVERSION;
+ ip->ip_hl = hlen >> 2;
+ ip->ip_off &= IP_DF;
+ ip->ip_id = htons(ip_id++);
+
+ /*
+ * Find interface for this packet in the routing
+ * table. Note each interface has placed itself
+ * in there at boot time, so calls to rtalloc
+ * degenerate to if_ifonnetof(ip->ip_dst.s_net).
+ */
+ if (ro == 0) {
+ ro = &iproute;
+ bzero((caddr_t)ro, sizeof (*ro));
+ }
+ if (ro->ro_rt == 0) {
+ ro->ro_dst.sa_family = AF_INET;
+ ((struct sockaddr_in *)&ro->ro_dst)->sin_addr = ip->ip_dst;
+ rtalloc(ro);
+ }
+ if (ro->ro_rt == 0 || (ifp = ro->ro_rt->rt_ifp) == 0) {
+ printf("no route to %x (from %x, len %d)\n",
+ ip->ip_dst.s_addr, ip->ip_src.s_addr, ip->ip_len);
+ goto bad;
+ }
+ dst = ro->ro_rt->rt_flags&RTF_DIRECT ?
+ (struct sockaddr *)&ro->ro_dst : &ro->ro_rt->rt_gateway;
+ if (ro == &iproute)
+ RTFREE(ro->ro_rt);
+ 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)
+ goto bad;
+ }