* Like m_pullup(), except a new mbuf is always allocated, and we allow * the amount of empty space before the data in the new mbuf to be specified * (in the event that the caller expects to prepend later). */
| 925 | * (in the event that the caller expects to prepend later). |
| 926 | */ |
| 927 | struct mbuf * |
| 928 | m_copyup(struct mbuf *n, int len, int dstoff) |
| 929 | { |
| 930 | struct mbuf *m; |
| 931 | int count, space; |
| 932 | |
| 933 | if (len > (MHLEN - dstoff)) |
| 934 | goto bad; |
| 935 | m = m_get(M_NOWAIT, n->m_type); |
| 936 | if (m == NULL) |
| 937 | goto bad; |
| 938 | if (n->m_flags & M_PKTHDR) |
| 939 | m_move_pkthdr(m, n); |
| 940 | m->m_data += dstoff; |
| 941 | space = &m->m_dat[MLEN] - (m->m_data + m->m_len); |
| 942 | do { |
| 943 | count = min(min(max(len, max_protohdr), space), n->m_len); |
| 944 | memcpy(mtod(m, caddr_t) + m->m_len, mtod(n, caddr_t), |
| 945 | (unsigned)count); |
| 946 | len -= count; |
| 947 | m->m_len += count; |
| 948 | n->m_len -= count; |
| 949 | space -= count; |
| 950 | if (n->m_len) |
| 951 | n->m_data += count; |
| 952 | else |
| 953 | n = m_free(n); |
| 954 | } while (len > 0 && n); |
| 955 | if (len > 0) { |
| 956 | (void) m_free(m); |
| 957 | goto bad; |
| 958 | } |
| 959 | m->m_next = n; |
| 960 | return (m); |
| 961 | bad: |
| 962 | m_freem(n); |
| 963 | return (NULL); |
| 964 | } |
| 965 | |
| 966 | /* |
| 967 | * Partition an mbuf chain in two pieces, returning the tail -- |
no test coverage detected