00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdlib.h>
00024 #include <stdio.h>
00025 #include <string.h>
00026 #include <unistd.h>
00027 #include <sys/time.h>
00028 #include <sys/types.h>
00029
00030 #include <libnetfilter_queue/libnetfilter_queue.h>
00031 #include <libnetfilter_queue/libipq.h>
00032
00033
00034
00035
00036
00037
00038
00039 enum {
00040 IPQ_ERR_NONE = 0,
00041 IPQ_ERR_IMPL,
00042 IPQ_ERR_HANDLE,
00043 IPQ_ERR_SOCKET,
00044 IPQ_ERR_BIND,
00045 IPQ_ERR_BUFFER,
00046 IPQ_ERR_RECV,
00047 IPQ_ERR_NLEOF,
00048 IPQ_ERR_ADDRLEN,
00049 IPQ_ERR_STRUNC,
00050 IPQ_ERR_RTRUNC,
00051 IPQ_ERR_NLRECV,
00052 IPQ_ERR_SEND,
00053 IPQ_ERR_SUPP,
00054 IPQ_ERR_RECVBUF,
00055 IPQ_ERR_TIMEOUT,
00056 IPQ_ERR_PROTOCOL
00057 };
00058 #define IPQ_MAXERR IPQ_ERR_PROTOCOL
00059
00060 struct ipq_errmap_t {
00061 int errcode;
00062 char *message;
00063 } ipq_errmap[] = {
00064 { IPQ_ERR_NONE, "Unknown error" },
00065 { IPQ_ERR_IMPL, "Implementation error" },
00066 { IPQ_ERR_HANDLE, "Unable to create netlink handle" },
00067 { IPQ_ERR_SOCKET, "Unable to create netlink socket" },
00068 { IPQ_ERR_BIND, "Unable to bind netlink socket" },
00069 { IPQ_ERR_BUFFER, "Unable to allocate buffer" },
00070 { IPQ_ERR_RECV, "Failed to receive netlink message" },
00071 { IPQ_ERR_NLEOF, "Received EOF on netlink socket" },
00072 { IPQ_ERR_ADDRLEN, "Invalid peer address length" },
00073 { IPQ_ERR_STRUNC, "Sent message truncated" },
00074 { IPQ_ERR_RTRUNC, "Received message truncated" },
00075 { IPQ_ERR_NLRECV, "Received error from netlink" },
00076 { IPQ_ERR_SEND, "Failed to send netlink message" },
00077 { IPQ_ERR_SUPP, "Operation not supported" },
00078 { IPQ_ERR_RECVBUF, "Receive buffer size invalid" },
00079 { IPQ_ERR_TIMEOUT, "Timeout"},
00080 { IPQ_ERR_PROTOCOL, "Invalid protocol specified" }
00081 };
00082
00083 static int ipq_errno = IPQ_ERR_NONE;
00084
00085 static char *ipq_strerror(int errcode)
00086 {
00087 if (errcode < 0 || errcode > IPQ_MAXERR)
00088 errcode = IPQ_ERR_IMPL;
00089 return ipq_errmap[errcode].message;
00090 }
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 struct ipq_handle *ipq_create_handle(u_int32_t flags, u_int32_t protocol)
00102 {
00103 int status;
00104 struct ipq_handle *h;
00105
00106 h = (struct ipq_handle *)malloc(sizeof(struct ipq_handle));
00107 if (h == NULL) {
00108 ipq_errno = IPQ_ERR_HANDLE;
00109 return NULL;
00110 }
00111
00112 memset(h, 0, sizeof(struct ipq_handle));
00113
00114 h->nfqnlh = nfq_open();
00115 if (!h->nfqnlh) {
00116 ipq_errno = IPQ_ERR_SOCKET;
00117 goto err_free;
00118 }
00119
00120 if (protocol == PF_INET)
00121 status = nfq_bind_pf(h->nfqnlh, PF_INET);
00122 else if (protocol == PF_INET6)
00123 status = nfq_bind_pf(h->nfqnlh, PF_INET6);
00124 else {
00125 ipq_errno = IPQ_ERR_PROTOCOL;
00126 goto err_close;
00127 }
00128 h->family = protocol;
00129 if (status < 0) {
00130 ipq_errno = IPQ_ERR_BIND;
00131 goto err_close;
00132 }
00133
00134 h->qh = nfq_create_queue(h->nfqnlh, 0, NULL, NULL);
00135 if (!h->qh) {
00136 ipq_errno = IPQ_ERR_BIND;
00137 goto err_close;
00138 }
00139
00140 return h;
00141
00142 err_close:
00143 nfq_close(h->nfqnlh);
00144 err_free:
00145 free(h);
00146 return NULL;
00147 }
00148
00149
00150
00151
00152
00153 int ipq_destroy_handle(struct ipq_handle *h)
00154 {
00155 if (h) {
00156 nfq_close(h->nfqnlh);
00157 free(h);
00158 }
00159 return 0;
00160 }
00161
00162 int ipq_set_mode(const struct ipq_handle *h,
00163 u_int8_t mode, size_t range)
00164 {
00165 return nfq_set_mode(h->qh, mode, range);
00166 }
00167
00168
00169
00170
00171
00172 ssize_t ipq_read(const struct ipq_handle *h,
00173 unsigned char *buf, size_t len, int timeout)
00174 {
00175 struct nfattr *tb[NFQA_MAX];
00176 struct nlmsghdr *nlh = (struct nlmsghdr *)buf;
00177 struct nfgenmsg *msg = NULL;
00178 struct nfattr *nfa;
00179
00180
00181
00182
00183
00184
00185
00186 nfa = nfnl_parse_hdr(nfq_nfnlh(h->nfqnlh), nlh, &msg);
00187 if (!msg || !nfa)
00188 return 0;
00189
00190 if (msg->nfgen_family != h->family)
00191 return 0;
00192
00193 nfnl_parse_attr(tb, NFQA_MAX, nfa, 0xffff);
00194
00195
00196 return 0;
00197 }
00198
00199 int ipq_message_type(const unsigned char *buf)
00200 {
00201 return ((struct nlmsghdr*)buf)->nlmsg_type;
00202 }
00203
00204 int ipq_get_msgerr(const unsigned char *buf)
00205 {
00206 struct nlmsghdr *h = (struct nlmsghdr *)buf;
00207 struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
00208 return -err->error;
00209 }
00210
00211 ipq_packet_msg_t *ipq_get_packet(const unsigned char *buf)
00212 {
00213 return NLMSG_DATA((struct nlmsghdr *)(buf));
00214 }
00215
00216 int ipq_set_verdict(const struct ipq_handle *h,
00217 ipq_id_t id,
00218 unsigned int verdict,
00219 size_t data_len,
00220 unsigned char *buf)
00221 {
00222 return nfq_set_verdict(h->qh, id, verdict, data_len, buf);
00223 }
00224
00225
00226 int ipq_ctl(const struct ipq_handle *h, int request, ...)
00227 {
00228 return 1;
00229 }
00230
00231 char *ipq_errstr(void)
00232 {
00233 return ipq_strerror(ipq_errno);
00234 }
00235
00236 void ipq_perror(const char *s)
00237 {
00238 if (s)
00239 fputs(s, stderr);
00240 else
00241 fputs("ERROR", stderr);
00242 if (ipq_errno)
00243 fprintf(stderr, ": %s", ipq_errstr());
00244 if (errno)
00245 fprintf(stderr, ": %s", strerror(errno));
00246 fputc('\n', stderr);
00247 }