Mercurial > hg > freeDiameter
comparison libfdproto/dictionary_functions.c @ 1122:d4371b7aa0ff
New CMake option: ADDRESS_AVP_INCLUDE_PORT. Turn off for standard Host-IP-Address AVPs
author | Sebastien Decugis <sdecugis@freediameter.net> |
---|---|
date | Tue, 14 May 2013 18:01:31 +0800 |
parents | 44f3e48dfe27 |
children | 140450615773 |
comparison
equal
deleted
inserted
replaced
1121:ccbd1426e04a | 1122:d4371b7aa0ff |
---|---|
71 /* We are encoding an IP address */ | 71 /* We are encoding an IP address */ |
72 sSA4 * sin = (sSA4 *)ss; | 72 sSA4 * sin = (sSA4 *)ss; |
73 | 73 |
74 AddressType = 1;/* see http://www.iana.org/assignments/address-family-numbers/ */ | 74 AddressType = 1;/* see http://www.iana.org/assignments/address-family-numbers/ */ |
75 size = 6; /* 2 for AddressType + 4 for data */ | 75 size = 6; /* 2 for AddressType + 4 for data */ |
76 #ifdef ADDRESS_AVP_INCLUDE_PORT | |
77 if (sin->sin_port != 0) | |
78 size += 2; | |
79 #endif /* ADDRESS_AVP_INCLUDE_PORT */ | |
76 | 80 |
77 CHECK_MALLOC( buf = malloc(size) ); | 81 CHECK_MALLOC( buf = malloc(size) ); |
78 | 82 |
79 /* may not work because of alignment: *(uint32_t *)(buf+2) = htonl(sin->sin_addr.s_addr); */ | 83 /* may not work because of alignment: *(uint32_t *)(buf+2) = htonl(sin->sin_addr.s_addr); */ |
80 memcpy(buf + 2, &sin->sin_addr.s_addr, 4); | 84 memcpy(buf + 2, &sin->sin_addr.s_addr, 4); |
85 | |
86 #ifdef ADDRESS_AVP_INCLUDE_PORT | |
87 if (sin->sin_port != 0) | |
88 memcpy(buf + 6, &sin->sin_port, 2); | |
89 #endif /* ADDRESS_AVP_INCLUDE_PORT */ | |
81 } | 90 } |
82 break; | 91 break; |
83 | 92 |
84 case AF_INET6: | 93 case AF_INET6: |
85 { | 94 { |
86 /* We are encoding an IPv6 address */ | 95 /* We are encoding an IPv6 address */ |
87 sSA6 * sin6 = (sSA6 *)ss; | 96 sSA6 * sin6 = (sSA6 *)ss; |
88 | 97 |
89 AddressType = 2;/* see http://www.iana.org/assignments/address-family-numbers/ */ | 98 AddressType = 2;/* see http://www.iana.org/assignments/address-family-numbers/ */ |
90 size = 18; /* 2 for AddressType + 16 for data */ | 99 size = 18; /* 2 for AddressType + 16 for data */ |
100 #ifdef ADDRESS_AVP_INCLUDE_PORT | |
101 if (sin6->sin6_port != 0) | |
102 size += 2; | |
103 #endif /* ADDRESS_AVP_INCLUDE_PORT */ | |
91 | 104 |
92 CHECK_MALLOC( buf = malloc(size) ); | 105 CHECK_MALLOC( buf = malloc(size) ); |
93 | 106 |
94 /* The order is already good here */ | 107 /* The order is already good here */ |
95 memcpy(buf + 2, &sin6->sin6_addr.s6_addr, 16); | 108 memcpy(buf + 2, &sin6->sin6_addr.s6_addr, 16); |
109 | |
110 #ifdef ADDRESS_AVP_INCLUDE_PORT | |
111 if (sin6->sin6_port != 0) | |
112 memcpy(buf + 18, &sin6->sin6_port, 2); | |
113 #endif /* ADDRESS_AVP_INCLUDE_PORT */ | |
96 } | 114 } |
97 break; | 115 break; |
98 | 116 |
99 default: | 117 default: |
100 CHECK_PARAMS( AddressType = 0 ); | 118 CHECK_PARAMS( AddressType = 0 ); |
123 switch (AddressType) { | 141 switch (AddressType) { |
124 case 1 /* IP */: | 142 case 1 /* IP */: |
125 { | 143 { |
126 sSA4 * sin = (sSA4 *)interpreted; | 144 sSA4 * sin = (sSA4 *)interpreted; |
127 | 145 |
128 CHECK_PARAMS( avp_value->os.len == 6 ); | 146 CHECK_PARAMS( avp_value->os.len >= 6 ); |
129 | 147 |
130 sin->sin_family = AF_INET; | 148 sin->sin_family = AF_INET; |
131 /* sin->sin_addr.s_addr = ntohl( * (uint32_t *) buf); -- may not work because of bad alignment */ | 149 /* sin->sin_addr.s_addr = ntohl( * (uint32_t *) buf); -- may not work because of bad alignment */ |
132 memcpy(&sin->sin_addr.s_addr, buf, 4); | 150 memcpy(&sin->sin_addr.s_addr, buf, 4); |
151 | |
152 if (avp_value->os.len == 8) | |
153 memcpy(&sin->sin_port, buf + 4, 2); | |
133 } | 154 } |
134 break; | 155 break; |
135 | 156 |
136 case 2 /* IP6 */: | 157 case 2 /* IP6 */: |
137 { | 158 { |
138 sSA6 * sin6 = (sSA6 *)interpreted; | 159 sSA6 * sin6 = (sSA6 *)interpreted; |
139 | 160 |
140 CHECK_PARAMS( avp_value->os.len == 18 ); | 161 CHECK_PARAMS( avp_value->os.len >= 18 ); |
141 | 162 |
142 sin6->sin6_family = AF_INET6; | 163 sin6->sin6_family = AF_INET6; |
143 memcpy(&sin6->sin6_addr.s6_addr, buf, 16); | 164 memcpy(&sin6->sin6_addr.s6_addr, buf, 16); |
165 | |
166 if (avp_value->os.len == 20) | |
167 memcpy(&sin6->sin6_port, buf + 16, 2); | |
168 | |
144 } | 169 } |
145 break; | 170 break; |
146 | 171 |
147 default: | 172 default: |
148 CHECK_PARAMS( AddressType = 0 ); | 173 CHECK_PARAMS( AddressType = 0 ); |
176 fam = avp_value->os.data[0] << 8 | avp_value->os.data[1]; | 201 fam = avp_value->os.data[0] << 8 | avp_value->os.data[1]; |
177 switch (fam) { | 202 switch (fam) { |
178 case 1: | 203 case 1: |
179 /* IP */ | 204 /* IP */ |
180 s.sa.sa_family = AF_INET; | 205 s.sa.sa_family = AF_INET; |
181 if (avp_value->os.len != 6) { | 206 if ((avp_value->os.len != 6) && (avp_value->os.len != 8)) { |
182 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[invalid IP length: %zd]", avp_value->os.len), return NULL); | 207 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[invalid IP length: %zd]", avp_value->os.len), return NULL); |
183 return *buf; | 208 return *buf; |
184 } | 209 } |
185 memcpy(&s.sin.sin_addr.s_addr, avp_value->os.data + 2, 4); | 210 memcpy(&s.sin.sin_addr.s_addr, avp_value->os.data + 2, 4); |
211 if (avp_value->os.len == 8) | |
212 memcpy(&s.sin.sin_port, avp_value->os.data + 6, 2); | |
186 break; | 213 break; |
187 case 2: | 214 case 2: |
188 /* IP6 */ | 215 /* IP6 */ |
189 s.sa.sa_family = AF_INET6; | 216 s.sa.sa_family = AF_INET6; |
190 if (avp_value->os.len != 18) { | 217 if ((avp_value->os.len != 18) && (avp_value->os.len != 20)) { |
191 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[invalid IP6 length: %zd]", avp_value->os.len), return NULL); | 218 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[invalid IP6 length: %zd]", avp_value->os.len), return NULL); |
192 return *buf; | 219 return *buf; |
193 } | 220 } |
194 memcpy(&s.sin6.sin6_addr.s6_addr, avp_value->os.data + 2, 16); | 221 memcpy(&s.sin6.sin6_addr.s6_addr, avp_value->os.data + 2, 16); |
222 if (avp_value->os.len == 20) | |
223 memcpy(&s.sin6.sin6_port, avp_value->os.data + 18, 2); | |
195 break; | 224 break; |
196 default: | 225 default: |
197 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[unsupported family: 0x%hx]", fam), return NULL); | 226 CHECK_MALLOC_DO( fd_dump_extend(FD_DUMP_STD_PARAMS, "[unsupported family: 0x%hx]", fam), return NULL); |
198 return *buf; | 227 return *buf; |
199 } | 228 } |
200 | 229 |
201 return fd_sa_dump_node(FD_DUMP_STD_PARAMS, &s.sa, NI_NUMERICHOST); | 230 return fd_sa_dump(FD_DUMP_STD_PARAMS, &s.sa, NI_NUMERICHOST); |
202 } | 231 } |
203 | 232 |
204 | 233 |
205 | 234 |
206 /*******************************/ | 235 /*******************************/ |