1 /* ip_output.c 1.7 81/10/31 */ 2 3 #include "../h/param.h" 4 #include "../h/mbuf.h" 5 #include "../h/socket.h" 6 #include "../inet/inet.h" 7 #include "../inet/inet_systm.h" 8 #include "../inet/imp.h" 9 #include "../inet/inet_host.h" 10 #include "../inet/ip.h" 11 #include "../inet/tcp.h" 12 13 ip_output(mp) 14 struct mbuf *mp; 15 { 16 register i, rnd; 17 register struct mbuf *m, *n; 18 register struct ip *p; 19 struct mbuf *mm; 20 int hlen, adj, max, len, off; 21 22 COUNT(IP_OUTPUT); 23 p = (struct ip *)((int)mp + mp->m_off); /* -> ip header */ 24 hlen = sizeof (struct ip); /* header length */ 25 26 /* 27 * Fill in and byte swap ip header. 28 */ 29 p->ip_v = IPVERSION; 30 p->ip_hl = hlen >> 2; 31 p->ip_off = 0 | (p->ip_off & IP_DF); 32 p->ip_ttl = MAXTTL; 33 p->ip_id = ip_id++; 34 35 if (p->ip_len <= MTU) 36 return (ip_send(p)); 37 if (p->ip_off & IP_DF) 38 return (0); 39 max = MTU - hlen; 40 len = p->ip_len - hlen; 41 off = 0; 42 m = mp; 43 while (len > 0) { 44 p->ip_off |= off >> 3; 45 i = -hlen; 46 while (m != NULL) { 47 i += m->m_len; 48 if (i > max) 49 break; 50 n = m; 51 m = m->m_next; 52 } 53 if (i < max || m == NULL) { 54 p->ip_off = p->ip_off &~ IP_MF; 55 p->ip_len = i + hlen; 56 return (ip_send(p)); 57 } 58 if ((mm = m_get(1)) == NULL) /* no more bufs */ 59 return(0); 60 p->ip_off |= IP_MF; 61 i -= m->m_len; 62 rnd = i & ~7; 63 adj = i - rnd; 64 p->ip_len = rnd + hlen; 65 n->m_next = NULL; 66 mm->m_next = m; 67 m = mm; 68 m->m_off = MMAXOFF - hlen - adj; 69 m->m_len = hlen + adj; 70 bcopy(p, (caddr_t)((int)m + m->m_off), hlen); 71 if (adj) { 72 n->m_len -= adj; 73 bcopy((caddr_t)((int)n + n->m_len + n->m_off), 74 (caddr_t)((int)m + m->m_off + hlen), adj); 75 } 76 ip_send(p); 77 p = (struct ip *)((int)m + m->m_off); 78 len -= rnd; 79 off += rnd; 80 } 81 } 82 83 ip_send(p) 84 struct ip *p; 85 { 86 register struct mbuf *m; 87 register struct imp *l; 88 int s; 89 COUNT(IP_SEND); 90 91 m = dtom(p); 92 l = (struct imp *)((int)m + m->m_off - L1822); 93 if ((l->i_shost = p->ip_src.s_host) == 0) 94 l->i_shost = 253; 95 if ((l->i_dhost = p->ip_dst.s_host) == 0) 96 l->i_dhost = 253; 97 l->i_type = IPTYPE; 98 p->ip_sum = 0; 99 p->ip_len = htons(p->ip_len); 100 p->ip_id = htons(p->ip_id); 101 p->ip_off = htons(p->ip_off); 102 p->ip_sum = cksum(m, sizeof(struct ip)); 103 m->m_off -= L1822; /* -> 1822 leader */ 104 m->m_len += L1822; 105 m->m_act = NULL; 106 #ifndef IMPLOOP 107 s = splimp(); 108 if (imp_stat.outq_head != NULL) 109 imp_stat.outq_tail->m_act = m; 110 else 111 imp_stat.outq_head = m; 112 imp_stat.outq_tail = m; 113 splx(s); 114 if (!imp_stat.outactive) 115 enstart(0); 116 #else 117 if (imp_stat.inq_head != NULL) 118 imp_stat.inq_tail->m_act = m; 119 else 120 imp_stat.inq_head = m; 121 imp_stat.inq_tail = m; 122 #endif IMPLOOP 123 return (1); 124 } 125