]> jfr.im git - irc/quakenet/newserv.git/blob - newsearch/ns-cidr.c
e57267a7a643ef7b3a9e104c9c5313c6bd51df5e
[irc/quakenet/newserv.git] / newsearch / ns-cidr.c
1 /*
2 * CIDR functionality
3 */
4
5 #include "newsearch.h"
6
7 #include <stdio.h>
8 #include <stdlib.h>
9
10 #include "../irc/irc_config.h"
11 #include "../lib/irc_string.h"
12 #include "../lib/irc_ipv6.h"
13
14 struct cidr_localdata {
15 unsigned int ip;
16 unsigned int mask;
17 };
18
19 void *cidr_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput);
20 void cidr_free(searchCtx *ctx, struct searchNode *thenode);
21
22 struct searchNode *cidr_parse(searchCtx *ctx, int argc, char **argv) {
23 struct searchNode *thenode, *convsn;
24 struct cidr_localdata *c;
25 unsigned char mask;
26 struct irc_in_addr ip;
27 char *p;
28 int ret;
29
30 if(argc != 1) {
31 parseError = "usage: cidr ip/mask";
32 return NULL;
33 }
34
35 if (!(convsn=argtoconststr("cidr", ctx, argv[0], &p)))
36 return NULL;
37
38 ret = ipmask_parse(p, &ip, &mask);
39 convsn->free(ctx, convsn);
40
41 if(!ret) {
42 parseError = "usage: cidr ip/mask";
43 return NULL;
44 }
45
46 if(!irc_in_addr_is_ipv4(&ip)) {
47 parseError = "cidr: sorry, no IPv6 yet";
48 return NULL;
49 }
50
51 /* ??? */
52 mask-=(128-32);
53 if(mask > 32) {
54 parseError = "cidr: bad mask supplied";
55 return NULL;
56 }
57
58 if (!(thenode=(struct searchNode *)malloc(sizeof (struct searchNode)))) {
59 parseError = "malloc: could not allocate memory for this search.";
60 return NULL;
61 }
62
63 thenode->returntype = RETURNTYPE_BOOL;
64 if (!(c = malloc(sizeof(struct cidr_localdata)))) {
65 /* couldn't malloc() memory for thenode->localdata, so free thenode to avoid leakage */
66 parseError = "malloc: could not allocate memory for this search.";
67 free(thenode);
68 return NULL;
69 }
70
71 if(!mask) {
72 c->mask = 0;
73 } else if(mask < 32) {
74 c->mask = 0xffffffff << (32 - mask);
75 }
76
77 c->ip = irc_in_addr_v4_to_int(&ip) & c->mask;
78
79 thenode->localdata = (void *)c;
80 thenode->free = cidr_free;
81 thenode->exe = cidr_exe;
82
83 return thenode;
84 }
85
86 void *cidr_exe(searchCtx *ctx, struct searchNode *thenode, void *theinput) {
87 nick *np = (nick *)theinput;
88 struct cidr_localdata *c = thenode->localdata;
89 unsigned int ip;
90 struct irc_in_addr *sin;
91
92 sin = &np->ipnode->prefix->sin;
93 if(!irc_in_addr_is_ipv4(sin))
94 return (void *)0;
95
96 ip = irc_in_addr_v4_to_int(sin);
97 if((ip & c->mask) == c->ip)
98 return (void *)1;
99
100 return (void *)0;
101 }
102
103 void cidr_free(searchCtx *ctx, struct searchNode *thenode) {
104 free(thenode->localdata);
105 free(thenode);
106 }