1c91307af2622f6625525f3c1f9c954376df950adChia-chi Yeh/* $NetBSD: isakmp_frag.c,v 1.4.6.1 2009/04/22 11:25:35 tteras Exp $ */ 20a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 30a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* Id: isakmp_frag.c,v 1.4 2004/11/13 17:31:36 manubsd Exp */ 40a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 50a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang/* 60a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Copyright (C) 2004 Emmanuel Dreyfus 70a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * All rights reserved. 80a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 90a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Redistribution and use in source and binary forms, with or without 100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * modification, are permitted provided that the following conditions 110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * are met: 120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 1. Redistributions of source code must retain the above copyright 130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * notice, this list of conditions and the following disclaimer. 140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 2. Redistributions in binary form must reproduce the above copyright 150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * notice, this list of conditions and the following disclaimer in the 160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * documentation and/or other materials provided with the distribution. 170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 3. Neither the name of the project nor the names of its contributors 180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * may be used to endorse or promote products derived from this software 190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * without specific prior written permission. 200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * 210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * SUCH DAMAGE. 320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "config.h" 350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/types.h> 370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/param.h> 380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/socket.h> 390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <sys/queue.h> 400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <netinet/in.h> 420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <arpa/inet.h> 430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <openssl/md5.h> 450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdlib.h> 470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <stdio.h> 480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <fcntl.h> 490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <string.h> 500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <errno.h> 510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#if TIME_WITH_SYS_TIME 520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# include <sys/time.h> 530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# include <time.h> 540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#else 550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# if HAVE_SYS_TIME_H 560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# include <sys/time.h> 570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# else 580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# include <time.h> 590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang# endif 600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <netdb.h> 620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#ifdef HAVE_UNISTD_H 630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <unistd.h> 640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#endif 650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include <ctype.h> 660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "var.h" 680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "misc.h" 690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "vmbuf.h" 700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "plog.h" 710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "sockmisc.h" 720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "schedule.h" 730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "debug.h" 740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_var.h" 760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp.h" 770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "handler.h" 780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "isakmp_frag.h" 790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang#include "strnames.h" 800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_sendfrags(iph1, buf) 830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct ph1handle *iph1; 840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *buf; 850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp *hdr; 870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp_frag *fraghdr; 880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang caddr_t data; 890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang caddr_t sdata; 900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang size_t datalen; 910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang size_t max_datalen; 920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang size_t fraglen; 930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *frag; 940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang unsigned int trailer; 950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang unsigned int fragnum = 0; 960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang size_t len; 970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int etype; 980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 1000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * Catch the exchange type for later: the fragments and the 1010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * fragmented packet must have the same exchange type. 1020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 1030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang hdr = (struct isakmp *)buf->v; 1040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang etype = hdr->etype; 1050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 1070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * We want to send a a packet smaller than ISAKMP_FRAG_MAXLEN 1080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * First compute the maximum data length that will fit in it 1090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 1100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang max_datalen = ISAKMP_FRAG_MAXLEN - 1110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang (sizeof(*hdr) + sizeof(*fraghdr) + sizeof(trailer)); 1120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang sdata = buf->v; 1140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang len = buf->l; 1150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang while (len > 0) { 1170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fragnum++; 1180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (len > max_datalen) 1200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang datalen = max_datalen; 1210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang else 1220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang datalen = len; 1230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fraglen = sizeof(*hdr) 1250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang + sizeof(*fraghdr) 1260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang + datalen; 1270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((frag = vmalloc(fraglen)) == NULL) { 1290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 1300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "Cannot allocate memory\n"); 1310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return -1; 1320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang set_isakmp_header1(frag, iph1, ISAKMP_NPTYPE_FRAG); 1350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang hdr = (struct isakmp *)frag->v; 1360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang hdr->etype = etype; 1370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fraghdr = (struct isakmp_frag *)(hdr + 1); 1390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fraghdr->unknown0 = htons(0); 1400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fraghdr->len = htons(fraglen - sizeof(*hdr)); 1410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fraghdr->unknown1 = htons(1); 1420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fraghdr->index = fragnum; 1430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (len == datalen) 1440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fraghdr->flags = ISAKMP_FRAG_LAST; 1450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang else 1460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang fraghdr->flags = 0; 1470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang data = (caddr_t)(fraghdr + 1); 1490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(data, sdata, datalen); 1500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (isakmp_send(iph1, frag) < 0) { 1520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, "isakmp_send failed\n"); 1530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return -1; 1540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(frag); 1570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang len -= datalen; 1590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang sdata += datalen; 1600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return fragnum; 1630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 1640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangunsigned int 1660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvendorid_frag_cap(gen) 1670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp_gen *gen; 1680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 1690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int *hp; 1700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang hp = (int *)(gen + 1); 1720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return ntohl(hp[MD5_DIGEST_LENGTH / sizeof(*hp)]); 1740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 1750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangint 1770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_frag_extract(iph1, msg) 1780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct ph1handle *iph1; 1790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *msg; 1800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 1810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp *isakmp; 1820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp_frag *frag; 1830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp_frag_item *item; 1840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *buf; 1850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang size_t len; 1860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int last_frag = 0; 1870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *data; 1880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int i; 1890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (msg->l < sizeof(*isakmp) + sizeof(*frag)) { 1910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, "Message too short\n"); 1920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return -1; 1930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 1940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang isakmp = (struct isakmp *)msg->v; 1960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang frag = (struct isakmp_frag *)(isakmp + 1); 1970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 1980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* 1990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * frag->len is the frag payload data plus the frag payload header, 2000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang * whose size is sizeof(*frag) 2010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang */ 2021c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh if (msg->l < sizeof(*isakmp) + ntohs(frag->len) || 2031c71527b277e2dc256262da2ed2169c566c5bf4dChia-chi Yeh ntohs(frag->len) < sizeof(*frag) + 1) { 2040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, "Fragment too short\n"); 2050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return -1; 2060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((buf = vmalloc(ntohs(frag->len) - sizeof(*frag))) == NULL) { 2090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 2100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return -1; 2110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((item = racoon_malloc(sizeof(*item))) == NULL) { 2140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 2150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(buf); 2160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return -1; 2170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang data = (char *)(frag + 1); 2200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(buf->v, data, buf->l); 2210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang item->frag_num = frag->index; 2230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang item->frag_last = (frag->flags & ISAKMP_FRAG_LAST); 2240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang item->frag_next = NULL; 2250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang item->frag_packet = buf; 2260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* Look for the last frag while inserting the new item in the chain */ 2280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (item->frag_last) 2290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang last_frag = item->frag_num; 2300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (iph1->frag_chain == NULL) { 2320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph1->frag_chain = item; 2330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } else { 2340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp_frag_item *current; 2350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang current = iph1->frag_chain; 2370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang while (current->frag_next) { 2380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (current->frag_last) 2390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang last_frag = item->frag_num; 2400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang current = current->frag_next; 2410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang current->frag_next = item; 2430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* If we saw the last frag, check if the chain is complete */ 2460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (last_frag != 0) { 2470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang for (i = 1; i <= last_frag; i++) { 2480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang item = iph1->frag_chain; 2490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang do { 2500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (item->frag_num == i) 2510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 2520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang item = item->frag_next; 2530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } while (item != NULL); 2540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (item == NULL) /* Not found */ 2560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 2570a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2580a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2590a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (item != NULL) /* It is complete */ 2600a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return 1; 2610a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2620a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2630a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return 0; 2640a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 2650a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2660a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t * 2670a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_frag_reassembly(iph1) 2680a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct ph1handle *iph1; 2690a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 2700a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp_frag_item *item; 2710a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang size_t len = 0; 2720a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *buf = NULL; 2730a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int frag_count = 0; 2740a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int i; 2750a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang char *data; 2760a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2770a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((item = iph1->frag_chain) == NULL) { 2780a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, "No fragment to reassemble\n"); 2790a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto out; 2800a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2810a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2820a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang do { 2830a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang frag_count++; 2840a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang len += item->frag_packet->l; 2850a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang item = item->frag_next; 2860a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } while (item != NULL); 2870a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2880a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((buf = vmalloc(len)) == NULL) { 2890a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n"); 2900a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto out; 2910a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 2920a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang data = buf->v; 2930a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 2940a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang for (i = 1; i <= frag_count; i++) { 2950a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang item = iph1->frag_chain; 2960a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang do { 2970a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (item->frag_num == i) 2980a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang break; 2990a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang item = item->frag_next; 3000a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } while (item != NULL); 3010a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3020a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (item == NULL) { 3030a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 3040a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "Missing fragment #%d\n", i); 3050a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(buf); 3060a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang buf = NULL; 3070a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang goto out; 3080a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3090a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang memcpy(data, item->frag_packet->v, item->frag_packet->l); 3100a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang data += item->frag_packet->l; 3110a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3120a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3130a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangout: 3140a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang item = iph1->frag_chain; 3150a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang do { 3160a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang struct isakmp_frag_item *next_item; 3170a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3180a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang next_item = item->frag_next; 3190a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3200a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vfree(item->frag_packet); 3210a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang racoon_free(item); 3220a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3230a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang item = next_item; 3240a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } while (item != NULL); 3250a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3260a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang iph1->frag_chain = NULL; 3270a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3280a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return buf; 3290a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 3300a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3310a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangvchar_t * 3320a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wangisakmp_frag_addcap(buf, cap) 3330a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang vchar_t *buf; 3340a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int cap; 3350a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang{ 3360a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang int *capp; 3370a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang size_t len; 3380a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3390a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang /* If the capability has not been added, add room now */ 3400a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang len = buf->l; 3410a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if (len == MD5_DIGEST_LENGTH) { 3420a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang if ((buf = vrealloc(buf, len + sizeof(cap))) == NULL) { 3430a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang plog(LLV_ERROR, LOCATION, NULL, 3440a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang "Cannot allocate memory\n"); 3450a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return NULL; 3460a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3470a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang capp = (int *)(buf->v + len); 3480a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *capp = htonl(0); 3490a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang } 3500a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3510a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang capp = (int *)(buf->v + MD5_DIGEST_LENGTH); 3520a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang *capp |= htonl(cap); 3530a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 3540a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang return buf; 3550a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang} 3560a1907d434839af6a9cb6329bbde60b237bf53dcChung-yih Wang 357