00001
00002
00003
00004
00005
00006
00007
00008 #include "internal/internal.h"
00009
00010 static int __snprintf_l3protocol(char *buf,
00011 unsigned int len,
00012 const struct nf_conntrack *ct)
00013 {
00014 return (snprintf(buf, len, "%-8s %u ",
00015 l3proto2str[ct->tuple[__DIR_ORIG].l3protonum] == NULL ?
00016 "unknown" : l3proto2str[ct->tuple[__DIR_ORIG].l3protonum],
00017 ct->tuple[__DIR_ORIG].l3protonum));
00018 }
00019
00020 int __snprintf_protocol(char *buf,
00021 unsigned int len,
00022 const struct nf_conntrack *ct)
00023 {
00024 return (snprintf(buf, len, "%-8s %u ",
00025 proto2str[ct->tuple[__DIR_ORIG].protonum] == NULL ?
00026 "unknown" : proto2str[ct->tuple[__DIR_ORIG].protonum],
00027 ct->tuple[__DIR_ORIG].protonum));
00028 }
00029
00030 static int __snprintf_timeout(char *buf,
00031 unsigned int len,
00032 const struct nf_conntrack *ct)
00033 {
00034 return snprintf(buf, len, "%u ", ct->timeout);
00035 }
00036
00037 static int __snprintf_protoinfo(char *buf,
00038 unsigned int len,
00039 const struct nf_conntrack *ct)
00040 {
00041 return snprintf(buf, len, "%s ",
00042 ct->protoinfo.tcp.state < TCP_CONNTRACK_MAX ?
00043 states[ct->protoinfo.tcp.state] :
00044 states[TCP_CONNTRACK_NONE]);
00045 }
00046
00047 static int __snprintf_protoinfo_sctp(char *buf,
00048 unsigned int len,
00049 const struct nf_conntrack *ct)
00050 {
00051 return snprintf(buf, len, "%s ",
00052 ct->protoinfo.sctp.state < SCTP_CONNTRACK_MAX ?
00053 sctp_states[ct->protoinfo.sctp.state] :
00054 sctp_states[SCTP_CONNTRACK_NONE]);
00055 }
00056
00057 static int __snprintf_protoinfo_dccp(char *buf,
00058 unsigned int len,
00059 const struct nf_conntrack *ct)
00060 {
00061 return snprintf(buf, len, "%s ",
00062 ct->protoinfo.dccp.state < DCCP_CONNTRACK_MAX ?
00063 sctp_states[ct->protoinfo.dccp.state] :
00064 sctp_states[DCCP_CONNTRACK_NONE]);
00065 }
00066
00067 static int __snprintf_address_ipv4(char *buf,
00068 unsigned int len,
00069 const struct __nfct_tuple *tuple)
00070 {
00071 int ret, size = 0, offset = 0;
00072 struct in_addr src = { .s_addr = tuple->src.v4 };
00073 struct in_addr dst = { .s_addr = tuple->dst.v4 };
00074
00075 ret = snprintf(buf, len, "src=%s ", inet_ntoa(src));
00076 BUFFER_SIZE(ret, size, len, offset);
00077
00078 ret = snprintf(buf+offset, len, "dst=%s ", inet_ntoa(dst));
00079 BUFFER_SIZE(ret, size, len, offset);
00080
00081 return size;
00082 }
00083
00084 static int __snprintf_address_ipv6(char *buf,
00085 unsigned int len,
00086 const struct __nfct_tuple *tuple)
00087 {
00088 int ret, size = 0, offset = 0;
00089 struct in6_addr src;
00090 struct in6_addr dst;
00091 char tmp[INET6_ADDRSTRLEN];
00092
00093 memcpy(&src, &tuple->src.v6, sizeof(struct in6_addr));
00094 memcpy(&dst, &tuple->dst.v6, sizeof(struct in6_addr));
00095
00096 if (!inet_ntop(AF_INET6, &src, tmp, sizeof(tmp)))
00097 return -1;
00098
00099 ret = snprintf(buf, len, "src=%s ", tmp);
00100 BUFFER_SIZE(ret, size, len, offset);
00101
00102 if (!inet_ntop(AF_INET6, &dst, tmp, sizeof(tmp)))
00103 return -1;
00104
00105 ret = snprintf(buf+offset, len-size, "dst=%s ", tmp);
00106 BUFFER_SIZE(ret, size, len, offset);
00107
00108 return size;
00109 }
00110
00111 int __snprintf_address(char *buf,
00112 unsigned int len,
00113 const struct __nfct_tuple *tuple)
00114 {
00115 int size = 0;
00116
00117 switch (tuple->l3protonum) {
00118 case AF_INET:
00119 size = __snprintf_address_ipv4(buf, len, tuple);
00120 break;
00121 case AF_INET6:
00122 size = __snprintf_address_ipv6(buf, len, tuple);
00123 break;
00124 }
00125
00126 return size;
00127 }
00128
00129 int __snprintf_proto(char *buf,
00130 unsigned int len,
00131 const struct __nfct_tuple *tuple)
00132 {
00133 int size = 0;
00134
00135 switch(tuple->protonum) {
00136 case IPPROTO_TCP:
00137 case IPPROTO_UDP:
00138 case IPPROTO_UDPLITE:
00139 case IPPROTO_SCTP:
00140 case IPPROTO_DCCP:
00141 return snprintf(buf, len, "sport=%u dport=%u ",
00142 ntohs(tuple->l4src.tcp.port),
00143 ntohs(tuple->l4dst.tcp.port));
00144 break;
00145 case IPPROTO_GRE:
00146 return snprintf(buf, len, "srckey=0x%x dstkey=0x%x ",
00147 ntohs(tuple->l4src.all),
00148 ntohs(tuple->l4dst.all));
00149 break;
00150 case IPPROTO_ICMP:
00151 case IPPROTO_ICMPV6:
00152
00153
00154 return (snprintf(buf, len, "type=%d code=%d id=%d ",
00155 tuple->l4dst.icmp.type,
00156 tuple->l4dst.icmp.code,
00157 ntohs(tuple->l4src.icmp.id)));
00158 break;
00159 }
00160
00161 return size;
00162 }
00163
00164 static int __snprintf_status_assured(char *buf,
00165 unsigned int len,
00166 const struct nf_conntrack *ct)
00167 {
00168 int size = 0;
00169
00170 if (ct->status & IPS_ASSURED)
00171 size = snprintf(buf, len, "[ASSURED] ");
00172
00173 return size;
00174 }
00175
00176 static int __snprintf_status_not_seen_reply(char *buf,
00177 unsigned int len,
00178 const struct nf_conntrack *ct)
00179 {
00180 int size = 0;
00181
00182 if (!(ct->status & IPS_SEEN_REPLY))
00183 size = snprintf(buf, len, "[UNREPLIED] ");
00184
00185 return size;
00186 }
00187
00188 static int __snprintf_counters(char *buf,
00189 unsigned int len,
00190 const struct nf_conntrack *ct,
00191 int dir)
00192 {
00193 return (snprintf(buf, len, "packets=%llu bytes=%llu ",
00194 (unsigned long long) ct->counters[dir].packets,
00195 (unsigned long long) ct->counters[dir].bytes));
00196 }
00197
00198 static int
00199 __snprintf_mark(char *buf, unsigned int len, const struct nf_conntrack *ct)
00200 {
00201 return (snprintf(buf, len, "mark=%u ", ct->mark));
00202 }
00203
00204 static int
00205 __snprintf_secmark(char *buf, unsigned int len, const struct nf_conntrack *ct)
00206 {
00207 return (snprintf(buf, len, "secmark=%u ", ct->secmark));
00208 }
00209
00210 static int
00211 __snprintf_use(char *buf, unsigned int len, const struct nf_conntrack *ct)
00212 {
00213 return (snprintf(buf, len, "use=%u ", ct->use));
00214 }
00215
00216 static int
00217 __snprintf_id(char *buf, unsigned int len, const struct nf_conntrack *ct)
00218 {
00219 return (snprintf(buf, len, "id=%u ", ct->id));
00220 }
00221
00222 static int
00223 __snprintf_zone(char *buf, unsigned int len, const struct nf_conntrack *ct)
00224 {
00225 return (snprintf(buf, len, "zone=%u ", ct->zone));
00226 }
00227
00228 static int
00229 __snprintf_secctx(char *buf, unsigned int len, const struct nf_conntrack *ct)
00230 {
00231 return (snprintf(buf, len, "secctx=%s ", ct->secctx));
00232 }
00233
00234 int __snprintf_conntrack_default(char *buf,
00235 unsigned int len,
00236 const struct nf_conntrack *ct,
00237 unsigned int msg_type,
00238 unsigned int flags)
00239 {
00240 int ret = 0, size = 0, offset = 0;
00241
00242 switch(msg_type) {
00243 case NFCT_T_NEW:
00244 ret = snprintf(buf, len, "%9s ", "[NEW]");
00245 break;
00246 case NFCT_T_UPDATE:
00247 ret = snprintf(buf, len, "%9s ", "[UPDATE]");
00248 break;
00249 case NFCT_T_DESTROY:
00250 ret = snprintf(buf, len, "%9s ", "[DESTROY]");
00251 break;
00252 default:
00253 break;
00254 }
00255
00256 BUFFER_SIZE(ret, size, len, offset);
00257
00258 if (flags & NFCT_OF_SHOW_LAYER3) {
00259 ret = __snprintf_l3protocol(buf+offset, len, ct);
00260 BUFFER_SIZE(ret, size, len, offset);
00261 }
00262
00263 ret = __snprintf_protocol(buf+offset, len, ct);
00264 BUFFER_SIZE(ret, size, len, offset);
00265
00266 if (test_bit(ATTR_TIMEOUT, ct->set)) {
00267 ret = __snprintf_timeout(buf+offset, len, ct);
00268 BUFFER_SIZE(ret, size, len, offset);
00269 }
00270
00271 if (test_bit(ATTR_TCP_STATE, ct->set)) {
00272 ret = __snprintf_protoinfo(buf+offset, len, ct);
00273 BUFFER_SIZE(ret, size, len, offset);
00274 }
00275
00276 if (test_bit(ATTR_SCTP_STATE, ct->set)) {
00277 ret = __snprintf_protoinfo_sctp(buf+offset, len, ct);
00278 BUFFER_SIZE(ret, size, len, offset);
00279 }
00280
00281 if (test_bit(ATTR_DCCP_STATE, ct->set)) {
00282 ret = __snprintf_protoinfo_dccp(buf+offset, len, ct);
00283 BUFFER_SIZE(ret, size, len, offset);
00284 }
00285
00286 ret = __snprintf_address(buf+offset, len, &ct->tuple[__DIR_ORIG]);
00287 BUFFER_SIZE(ret, size, len, offset);
00288
00289 ret = __snprintf_proto(buf+offset, len, &ct->tuple[__DIR_ORIG]);
00290 BUFFER_SIZE(ret, size, len, offset);
00291
00292 if (test_bit(ATTR_ORIG_COUNTER_PACKETS, ct->set) &&
00293 test_bit(ATTR_ORIG_COUNTER_BYTES, ct->set)) {
00294 ret = __snprintf_counters(buf+offset, len, ct, __DIR_ORIG);
00295 BUFFER_SIZE(ret, size, len, offset);
00296 }
00297
00298 if (test_bit(ATTR_STATUS, ct->set)) {
00299 ret = __snprintf_status_not_seen_reply(buf+offset, len, ct);
00300 BUFFER_SIZE(ret, size, len, offset);
00301 }
00302
00303 ret = __snprintf_address(buf+offset, len, &ct->tuple[__DIR_REPL]);
00304 BUFFER_SIZE(ret, size, len, offset);
00305
00306 ret = __snprintf_proto(buf+offset, len, &ct->tuple[__DIR_REPL]);
00307 BUFFER_SIZE(ret, size, len, offset);
00308
00309 if (test_bit(ATTR_REPL_COUNTER_PACKETS, ct->set) &&
00310 test_bit(ATTR_REPL_COUNTER_BYTES, ct->set)) {
00311 ret = __snprintf_counters(buf+offset, len, ct, __DIR_REPL);
00312 BUFFER_SIZE(ret, size, len, offset);
00313 }
00314
00315 if (test_bit(ATTR_STATUS, ct->set)) {
00316 ret = __snprintf_status_assured(buf+offset, len, ct);
00317 BUFFER_SIZE(ret, size, len, offset);
00318 }
00319
00320 if (test_bit(ATTR_MARK, ct->set)) {
00321 ret = __snprintf_mark(buf+offset, len, ct);
00322 BUFFER_SIZE(ret, size, len, offset);
00323 }
00324
00325 if (test_bit(ATTR_SECMARK, ct->set)) {
00326 ret = __snprintf_secmark(buf+offset, len, ct);
00327 BUFFER_SIZE(ret, size, len, offset);
00328 }
00329
00330 if (test_bit(ATTR_SECCTX, ct->set)) {
00331 ret = __snprintf_secctx(buf+offset, len, ct);
00332 BUFFER_SIZE(ret, size, len, offset);
00333 }
00334
00335 if (test_bit(ATTR_ZONE, ct->set)) {
00336 ret = __snprintf_zone(buf+offset, len, ct);
00337 BUFFER_SIZE(ret, size, len, offset);
00338 }
00339
00340 if (test_bit(ATTR_USE, ct->set)) {
00341 ret = __snprintf_use(buf+offset, len, ct);
00342 BUFFER_SIZE(ret, size, len, offset);
00343 }
00344
00345 if (flags & NFCT_OF_ID && test_bit(ATTR_ID, ct->set)) {
00346 ret = __snprintf_id(buf+offset, len, ct);
00347 BUFFER_SIZE(ret, size, len, offset);
00348 }
00349
00350
00351 size--;
00352
00353 return size;
00354 }