m will not be freed nor modified */
| 1845 | |
| 1846 | /* m will not be freed nor modified */ |
| 1847 | static struct mbuf * |
| 1848 | key_gather_mbuf(struct mbuf *m, const struct sadb_msghdr *mhp, |
| 1849 | int ndeep, int nitem, ...) |
| 1850 | { |
| 1851 | va_list ap; |
| 1852 | int idx; |
| 1853 | int i; |
| 1854 | struct mbuf *result = NULL, *n; |
| 1855 | int len; |
| 1856 | |
| 1857 | IPSEC_ASSERT(m != NULL, ("null mbuf")); |
| 1858 | IPSEC_ASSERT(mhp != NULL, ("null msghdr")); |
| 1859 | |
| 1860 | va_start(ap, nitem); |
| 1861 | for (i = 0; i < nitem; i++) { |
| 1862 | idx = va_arg(ap, int); |
| 1863 | if (idx < 0 || idx > SADB_EXT_MAX) |
| 1864 | goto fail; |
| 1865 | /* don't attempt to pull empty extension */ |
| 1866 | if (idx == SADB_EXT_RESERVED && mhp->msg == NULL) |
| 1867 | continue; |
| 1868 | if (idx != SADB_EXT_RESERVED && |
| 1869 | (mhp->ext[idx] == NULL || mhp->extlen[idx] == 0)) |
| 1870 | continue; |
| 1871 | |
| 1872 | if (idx == SADB_EXT_RESERVED) { |
| 1873 | len = PFKEY_ALIGN8(sizeof(struct sadb_msg)); |
| 1874 | |
| 1875 | IPSEC_ASSERT(len <= MHLEN, ("header too big %u", len)); |
| 1876 | |
| 1877 | MGETHDR(n, M_NOWAIT, MT_DATA); |
| 1878 | if (!n) |
| 1879 | goto fail; |
| 1880 | n->m_len = len; |
| 1881 | n->m_next = NULL; |
| 1882 | m_copydata(m, 0, sizeof(struct sadb_msg), |
| 1883 | mtod(n, caddr_t)); |
| 1884 | } else if (i < ndeep) { |
| 1885 | len = mhp->extlen[idx]; |
| 1886 | n = m_get2(len, M_NOWAIT, MT_DATA, 0); |
| 1887 | if (n == NULL) |
| 1888 | goto fail; |
| 1889 | m_align(n, len); |
| 1890 | n->m_len = len; |
| 1891 | m_copydata(m, mhp->extoff[idx], mhp->extlen[idx], |
| 1892 | mtod(n, caddr_t)); |
| 1893 | } else { |
| 1894 | n = m_copym(m, mhp->extoff[idx], mhp->extlen[idx], |
| 1895 | M_NOWAIT); |
| 1896 | } |
| 1897 | if (n == NULL) |
| 1898 | goto fail; |
| 1899 | |
| 1900 | if (result) |
| 1901 | m_cat(result, n); |
| 1902 | else |
| 1903 | result = n; |
| 1904 | } |
no test coverage detected