/* User-kernel network link */
+/*
+ * This file is part of secnet.
+ * See README for full list of copyright holders.
+ *
+ * secnet is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * secnet is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 3 along with secnet; if not, see
+ * https://www.gnu.org/licenses/gpl.html.
+ */
+
/* See RFCs 791, 792, 1123 and 1812 */
/* The netlink device is actually a router. Tunnels are unnumbered
/* We include the first 8 bytes of the packet data, provided they exist */
hlen+=8;
plen=ntohs(iph->tot_len);
- return (hlen>plen?plen:hlen);
+ return MIN(hlen,plen);
}
/* client indicates where the packet we're constructing a response to
len=netlink_icmp_reply_len(buf);
h=netlink_icmp_tmpl(st,icmpsource,icmpdest,len);
h->type=type; h->code=code; h->d=info;
- memcpy(buf_append(&st->icmp,len),buf->start,len);
+ BUF_ADD_BYTES(append,&st->icmp,buf->start,len);
netlink_icmp_csum(h);
if (!st->ptp) {
struct iphdr *iph=(struct iphdr *)buf->start;
int32_t len;
- if (iph->ihl < 5) BAD("ihl %u",iph->ihl);
if (iph->version != 4) BAD("version %u",iph->version);
+ if (iph->ihl < 5) BAD("ihl %u",iph->ihl);
if (buf->size < iph->ihl*4) BAD("size %"PRId32"<%u*4",buf->size,iph->ihl);
if (ip_fast_csum((uint8_t *)iph, iph->ihl)!=0) BAD("csum");
len=ntohs(iph->tot_len);
long avail = mtu - hl;
long remain = endindata - indata;
long use = avail < remain ? (avail & ~(long)7) : remain;
- memcpy(buf_append(buf, use), indata, use);
+ BUF_ADD_BYTES(append, buf, indata, use);
indata += use;
_Bool last_frag = indata >= endindata;
d=ipaddr_to_string(dest);
Message(M_ERR,"%s: dropping %s->%s, client not registered\n",
st->name,s,d);
- free(s); free(d);
BUF_FREE(buf);
return;
}
d=ipaddr_to_string(dest);
Message(M_DEBUG,"%s: don't know where to deliver packet "
"(s=%s, d=%s)\n", st->name, s, d);
- free(s); free(d);
netlink_icmp_simple(st,sender,buf,ICMP_TYPE_UNREACHABLE,
ICMP_CODE_NET_UNREACHABLE, icmp_noinfo);
BUF_FREE(buf);
with destination network administratively prohibited */
Message(M_NOTICE,"%s: denied forwarding for packet (s=%s, d=%s)\n",
st->name,s,d);
- free(s); free(d);
netlink_icmp_simple(st,sender,buf,ICMP_TYPE_UNREACHABLE,
ICMP_CODE_NET_PROHIBITED, icmp_noinfo);
d=ipaddr_to_string(dest);
Message(M_WARNING,"%s: packet from tunnel %s with bad "
"source address (s=%s,d=%s)\n",st->name,sender->name,s,d);
- free(s); free(d);
BUF_FREE(buf);
return;
}
d=ipaddr_to_string(dest);
Message(M_WARNING,"%s: outgoing packet with bad source address "
"(s=%s,d=%s)\n",st->name,s,d);
- free(s); free(d);
BUF_FREE(buf);
return;
}
for (i=0; i<snets->entries; i++) {
net=subnet_to_string(snets->list[i]);
Message(loglevel,"%s ",net);
- free(net);
}
}
net=ipaddr_to_string(st->secnet_address);
Message(c,"%s: point-to-point (remote end is %s); routes: ",
st->name, net);
- free(net);
netlink_output_subnets(st,c,st->clients->subnets);
Message(c,"\n");
} else {
net=ipaddr_to_string(st->secnet_address);
Message(c,"%s/32 -> netlink \"%s\" (use %d)\n",
net,st->name,st->localcount);
- free(net);
for (i=0; i<st->subnets->entries; i++) {
net=subnet_to_string(st->subnets->list[i]);
Message(c,"%s ",net);
- free(net);
}
if (i>0)
Message(c,"-> host (use %d)\n",st->outcount);
/* All the networks serviced by the various tunnels should now
* have been registered. We build a routing table by sorting the
* clients by priority. */
- st->routes=safe_malloc_ary(sizeof(*st->routes),st->n_clients,
- "netlink_phase_hook");
+ NEW_ARY(st->routes,st->n_clients);
/* Fill the table */
i=0;
for (c=st->clients; c; c=c->next) {
return NULL;
}
- c=safe_malloc(sizeof(*c),"netlink_inst_create");
+ NEW(c);
c->cl.description=name;
c->cl.type=CL_NETLINK;
c->cl.apply=NULL;
item_t *item;
dict_t *dict;
- st=safe_malloc(sizeof(*st),"null_apply");
+ NEW(st);
item=list_elem(args,0);
if (!item || item->type!=t_dict)