#include "netlink.h"
#include "process.h"
-#define OPT_SOFTROUTE 1
-#define OPT_ALLOWROUTE 2
-
#define ICMP_TYPE_ECHO_REPLY 0
#define ICMP_TYPE_UNREACHABLE 3
#define ICMP_CODE_TTL_EXCEEDED 0
/* Generic IP checksum routine */
-static inline uint16_t ip_csum(uint8_t *iph,uint32_t count)
+static inline uint16_t ip_csum(uint8_t *iph,int32_t count)
{
register uint32_t sum=0;
* By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
* Arnt Gulbrandsen.
*/
-static inline uint16_t ip_fast_csum(uint8_t *iph, uint32_t ihl) {
+static inline uint16_t ip_fast_csum(uint8_t *iph, int32_t ihl) {
uint32_t sum;
__asm__ __volatile__(
return sum;
}
#else
-static inline uint16_t ip_fast_csum(uint8_t *iph, uint32_t ihl)
+static inline uint16_t ip_fast_csum(uint8_t *iph, int32_t ihl)
{
+ assert(ihl < INT_MAX/4);
return ip_csum(iph,ihl*4);
}
#endif
/* Fill in the ICMP checksum field correctly */
static void netlink_icmp_csum(struct icmphdr *h)
{
- uint32_t len;
+ int32_t len;
len=ntohs(h->iph.tot_len)-(4*h->iph.ihl);
h->check=0;
* 3. Checksums correctly.
* 4. Doesn't have a bogus length
*/
-static bool_t netlink_check(struct netlink *st, struct buffer_if *buf)
+static bool_t netlink_check(struct netlink *st, struct buffer_if *buf,
+ char *errmsgbuf, int errmsgbuflen)
{
+#define BAD(...) do{ \
+ snprintf(errmsgbuf,errmsgbuflen,__VA_ARGS__); \
+ return False; \
+ }while(0)
+
struct iphdr *iph=(struct iphdr *)buf->start;
- uint32_t len;
+ int32_t len;
- if (iph->ihl < 5 || iph->version != 4) return False;
- if (buf->size < iph->ihl*4) return False;
- if (ip_fast_csum((uint8_t *)iph, iph->ihl)!=0) return False;
+ if (iph->ihl < 5) BAD("ihl %u",iph->ihl);
+ if (iph->version != 4) BAD("version %u",iph->version);
+ 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);
/* There should be no padding */
- if (buf->size!=len || len<(iph->ihl<<2)) return False;
+ if (buf->size!=len) BAD("len %"PRId32"!=%"PRId32,buf->size,len);
+ if (len<(iph->ihl<<2)) BAD("len %"PRId32"<(%u<<2)",len,iph->ihl);
/* XXX check that there's no source route specified */
return True;
+
+#undef BAD
}
/* Deliver a packet. "client" is the _origin_ of the packet, not its
{
uint32_t source,dest;
struct iphdr *iph;
+ char errmsgbuf[50];
BUF_ASSERT_USED(buf);
- if (!netlink_check(st,buf)) {
- Message(M_WARNING,"%s: bad IP packet from %s\n",
- st->name,client?client->name:"host");
+ if (!netlink_check(st,buf,errmsgbuf,sizeof(errmsgbuf))) {
+ Message(M_WARNING,"%s: bad IP packet from %s: %s\n",
+ st->name,client?client->name:"host",
+ errmsgbuf);
BUF_FREE(buf);
return;
}
static void netlink_output_subnets(struct netlink *st, uint32_t loglevel,
struct subnet_list *snets)
{
- uint32_t i;
+ int32_t i;
string_t net;
for (i=0; i<snets->entries; i++) {
{
struct netlink *st=sst;
struct netlink_client *c;
- uint32_t i;
+ int32_t i;
/* All the networks serviced by the various tunnels should now
* have been registered. We build a routing table by sorting the
netlink_dump_routes(st,True);
}
-static void netlink_inst_output_config(void *sst, struct buffer_if *buf)
-{
-/* struct netlink_client *c=sst; */
-/* struct netlink *st=c->nst; */
-
- /* For now we don't output anything */
- BUF_ASSERT_USED(buf);
-}
-
-static bool_t netlink_inst_check_config(void *sst, struct buffer_if *buf)
-{
-/* struct netlink_client *c=sst; */
-/* struct netlink *st=c->nst; */
-
- BUF_ASSERT_USED(buf);
- /* We need to eat all of the configuration information from the buffer
- for backward compatibility. */
- buf->size=0;
- return True;
-}
-
-static void netlink_inst_set_mtu(void *sst, uint32_t new_mtu)
+static void netlink_inst_set_mtu(void *sst, int32_t new_mtu)
{
struct netlink_client *c=sst;
}
static void netlink_inst_reg(void *sst, netlink_deliver_fn *deliver,
- void *dst, uint32_t max_start_pad,
- uint32_t max_end_pad)
+ void *dst, int32_t max_start_pad,
+ int32_t max_end_pad)
{
struct netlink_client *c=sst;
struct netlink *st=c->nst;
struct netlink_client *c;
string_t name;
struct ipset *networks;
- uint32_t options,priority,mtu;
+ uint32_t options,priority;
+ int32_t mtu;
list_t *l;
name=dict_read_string(dict, "name", True, st->name, loc);
c->ops.reg=netlink_inst_reg;
c->ops.deliver=netlink_inst_incoming;
c->ops.set_quality=netlink_set_quality;
- c->ops.output_config=netlink_inst_output_config;
- c->ops.check_config=netlink_inst_check_config;
c->ops.set_mtu=netlink_inst_set_mtu;
c->nst=st;
c->deliver=NULL;
c->dst=NULL;
c->name=name;
- c->link_quality=LINK_QUALITY_DOWN;
+ c->link_quality=LINK_QUALITY_UNUSED;
c->mtu=mtu?mtu:st->mtu;
c->options=options;
c->outcount=0;