1 /* 2 * (C) 2005-2011 by Pablo Neira Ayuso <pablo (at) netfilter.org> 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 */ 9 10 #include "internal/internal.h" 11 12 static int 13 __snprintf_expect_timeout(char *buf, unsigned int len, 14 const struct nf_expect *exp) 15 { 16 if (test_bit(ATTR_EXP_TIMEOUT, exp->set)) 17 return snprintf(buf, len, "%u ", exp->timeout); 18 19 return 0; 20 } 21 22 static int 23 __snprintf_expect_class(char *buf, unsigned int len, 24 const struct nf_expect *exp) 25 { 26 if (test_bit(ATTR_EXP_CLASS, exp->set)) 27 return snprintf(buf, len, "class=%u ", exp->class); 28 29 return 0; 30 } 31 32 static int __snprintf_expect_proto(char *buf, 33 unsigned int len, 34 const struct nf_expect *exp) 35 { 36 return(snprintf(buf, len, "proto=%d ", 37 exp->expected.orig.protonum)); 38 } 39 40 int __snprintf_expect_default(char *buf, 41 unsigned int len, 42 const struct nf_expect *exp, 43 unsigned int msg_type, 44 unsigned int flags) 45 { 46 int ret = 0, size = 0, offset = 0; 47 const char *delim = ""; 48 49 switch(msg_type) { 50 case NFCT_T_NEW: 51 ret = snprintf(buf, len, "%9s ", "[NEW]"); 52 break; 53 case NFCT_T_UPDATE: 54 ret = snprintf(buf, len, "%9s ", "[UPDATE]"); 55 break; 56 case NFCT_T_DESTROY: 57 ret = snprintf(buf, len, "%9s ", "[DESTROY]"); 58 break; 59 default: 60 break; 61 } 62 63 BUFFER_SIZE(ret, size, len, offset); 64 65 ret = __snprintf_expect_timeout(buf+offset, len, exp); 66 BUFFER_SIZE(ret, size, len, offset); 67 68 ret = __snprintf_expect_proto(buf+offset, len, exp); 69 BUFFER_SIZE(ret, size, len, offset); 70 71 ret = __snprintf_address(buf+offset, len, &exp->expected.orig, 72 "src", "dst"); 73 BUFFER_SIZE(ret, size, len, offset); 74 75 ret = __snprintf_proto(buf+offset, len, &exp->expected.orig); 76 BUFFER_SIZE(ret, size, len, offset); 77 78 ret = __snprintf_address(buf+offset, len, &exp->mask.orig, 79 "mask-src", "mask-dst"); 80 BUFFER_SIZE(ret, size, len, offset); 81 82 ret = __snprintf_proto(buf+offset, len, 83 &exp->mask.orig); 84 BUFFER_SIZE(ret, size, len, offset); 85 86 ret = __snprintf_address(buf+offset, len, &exp->master.orig, 87 "master-src", "master-dst"); 88 BUFFER_SIZE(ret, size, len, offset); 89 90 ret = __snprintf_proto(buf+offset, len, 91 &exp->master.orig); 92 BUFFER_SIZE(ret, size, len, offset); 93 94 if (test_bit(ATTR_EXP_ZONE, exp->set)) { 95 ret = snprintf(buf+offset, len, "zone=%u ", exp->zone); 96 BUFFER_SIZE(ret, size, len, offset); 97 } 98 99 if (exp->flags & NF_CT_EXPECT_PERMANENT) { 100 ret = snprintf(buf+offset, len, "PERMANENT"); 101 BUFFER_SIZE(ret, size, len, offset); 102 delim = ","; 103 } 104 if (exp->flags & NF_CT_EXPECT_INACTIVE) { 105 ret = snprintf(buf+offset, len, "%sINACTIVE", delim); 106 BUFFER_SIZE(ret, size, len, offset); 107 delim = ","; 108 } 109 if (exp->flags & NF_CT_EXPECT_USERSPACE) { 110 ret = snprintf(buf+offset, len, "%sUSERSPACE", delim); 111 BUFFER_SIZE(ret, size, len, offset); 112 } 113 /* extra space not to stick to next field. */ 114 if (exp->flags) { 115 ret = snprintf(buf+offset, len, " "); 116 BUFFER_SIZE(ret, size, len, offset); 117 } 118 ret = __snprintf_expect_class(buf+offset, len, exp); 119 BUFFER_SIZE(ret, size, len, offset); 120 121 if (test_bit(ATTR_EXP_HELPER_NAME, exp->set)) { 122 ret = snprintf(buf+offset, len, "helper=%s", exp->helper_name); 123 BUFFER_SIZE(ret, size, len, offset); 124 } 125 126 /* Delete the last blank space if needed */ 127 if (len > 0 && buf[size-1] == ' ') 128 size--; 129 130 return size; 131 } 132