Mercurial > hg > freeDiameter
comparison extensions/app_radgw/rgwx_acct.c @ 358:7ea43915cade
Fix: added the Destination-Realm also
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Thu, 01 Jul 2010 16:02:43 +0900 |
parents | e203fc0c95e3 |
children | ea6823f46fe8 |
comparison
equal
deleted
inserted
replaced
357:dda9330aa711 | 358:7ea43915cade |
---|---|
301 | 301 |
302 const char * prefix = "Diameter/"; | 302 const char * prefix = "Diameter/"; |
303 size_t pref_len; | 303 size_t pref_len; |
304 char * si = NULL; | 304 char * si = NULL; |
305 size_t si_len = 0; | 305 size_t si_len = 0; |
306 char * un = NULL; | |
307 size_t un_len = 0; | |
306 | 308 |
307 TRACE_ENTRY("%p %p %p %p %p %p", cs, session, rad_req, rad_ans, diam_fw, cli); | 309 TRACE_ENTRY("%p %p %p %p %p %p", cs, session, rad_req, rad_ans, diam_fw, cli); |
308 CHECK_PARAMS(rad_req && (rad_req->hdr->code == RADIUS_CODE_ACCOUNTING_REQUEST) && rad_ans && diam_fw && *diam_fw); | 310 CHECK_PARAMS(rad_req && (rad_req->hdr->code == RADIUS_CODE_ACCOUNTING_REQUEST) && rad_ans && diam_fw && *diam_fw); |
309 | 311 |
310 pref_len = strlen(prefix); | 312 pref_len = strlen(prefix); |
317 */ | 319 */ |
318 /* We also enforce that the message contains a CLASS attribute with Diameter/ prefix containing the Session-Id. */ | 320 /* We also enforce that the message contains a CLASS attribute with Diameter/ prefix containing the Session-Id. */ |
319 for (idx = 0; idx < rad_req->attr_used; idx++) { | 321 for (idx = 0; idx < rad_req->attr_used; idx++) { |
320 struct radius_attr_hdr * attr = (struct radius_attr_hdr *)(rad_req->buf + rad_req->attr_pos[idx]); | 322 struct radius_attr_hdr * attr = (struct radius_attr_hdr *)(rad_req->buf + rad_req->attr_pos[idx]); |
321 uint8_t * v = (uint8_t *)(attr + 1); | 323 uint8_t * v = (uint8_t *)(attr + 1); |
324 size_t attr_len = attr->length - sizeof(struct radius_attr_hdr); | |
325 | |
322 switch (attr->type) { | 326 switch (attr->type) { |
323 case RADIUS_ATTR_NAS_IP_ADDRESS: | 327 case RADIUS_ATTR_NAS_IP_ADDRESS: |
324 case RADIUS_ATTR_NAS_IDENTIFIER: | 328 case RADIUS_ATTR_NAS_IDENTIFIER: |
325 case RADIUS_ATTR_NAS_IPV6_ADDRESS: | 329 case RADIUS_ATTR_NAS_IPV6_ADDRESS: |
326 got_id = 1; | 330 got_id = 1; |
349 | (v[2] << 8) | 353 | (v[2] << 8) |
350 | v[3] ; | 354 | v[3] ; |
351 break; | 355 break; |
352 | 356 |
353 case RADIUS_ATTR_CLASS: | 357 case RADIUS_ATTR_CLASS: |
354 { | 358 if ((attr_len > pref_len ) && ! strncmp((char *)v, prefix, pref_len)) { |
355 char * attr_val = (char *)(attr + 1); | 359 int i; |
356 size_t attr_len = attr->length - sizeof(struct radius_attr_hdr); | 360 si = (char *)v + pref_len; |
357 if ((attr_len > pref_len ) && ! strncmp(attr_val, prefix, pref_len)) { | 361 si_len = attr_len - pref_len; |
358 int i; | 362 TRACE_DEBUG(ANNOYING, "Found Class attribute with '%s' prefix (attr #%d), SI:'%.*s'.", prefix, idx, si_len, si); |
359 si = attr_val + pref_len; | 363 /* Remove from the message */ |
360 si_len = attr_len - pref_len; | 364 for (i = idx + 1; i < rad_req->attr_used; i++) |
361 TRACE_DEBUG(ANNOYING, "Found Class attribute with '%s' prefix (attr #%d), SI:'%.*s'.", prefix, idx, si_len, si); | 365 rad_req->attr_pos[i - 1] = rad_req->attr_pos[i]; |
362 /* Remove from the message */ | 366 rad_req->attr_used -= 1; |
363 for (i = idx + 1; i < rad_req->attr_used; i++) | |
364 rad_req->attr_pos[i - 1] = rad_req->attr_pos[i]; | |
365 rad_req->attr_used -= 1; | |
366 break; | |
367 } | |
368 } | 367 } |
369 break; | 368 break; |
370 | 369 |
370 case RADIUS_ATTR_USER_NAME: | |
371 if (attr_len) { | |
372 un = (char *)v; | |
373 un_len = attr_len; | |
374 TRACE_DEBUG(ANNOYING, "Found a User-Name attribute: '%.*s'", un_len, un); | |
375 } | |
376 break; | |
377 | |
371 } | 378 } |
372 } | 379 } |
373 | 380 |
374 /* Check basic information is there */ | 381 /* Check basic information is there */ |
375 if (!got_id || radius_msg_get_attr_int32(rad_req, RADIUS_ATTR_ACCT_STATUS_TYPE, &status_type)) { | 382 if (!got_id || radius_msg_get_attr_int32(rad_req, RADIUS_ATTR_ACCT_STATUS_TYPE, &status_type)) { |
448 if (!*session && !si) { | 455 if (!*session && !si) { |
449 TRACE_DEBUG(INFO, "[acct.rgwx] RADIUS Account-Request from %s did not contain a CLASS attribute with Diameter session information, reject.", rgw_clients_id(cli)); | 456 TRACE_DEBUG(INFO, "[acct.rgwx] RADIUS Account-Request from %s did not contain a CLASS attribute with Diameter session information, reject.", rgw_clients_id(cli)); |
450 return EINVAL; | 457 return EINVAL; |
451 } | 458 } |
452 | 459 |
460 /* Add the Destination-Realm */ | |
461 CHECK_FCT( fd_msg_avp_new ( cs->dict.Destination_Realm, 0, &avp ) ); | |
462 idx = 0; | |
463 if (un) { | |
464 /* Is there an '@' in the user name? We don't care for decorated NAI here */ | |
465 for (idx = un_len - 2; idx > 0; idx--) { | |
466 if (un[idx] == '@') { | |
467 idx++; | |
468 break; | |
469 } | |
470 } | |
471 } | |
472 if (idx == 0) { | |
473 /* Not found in the User-Name => we use the local domain of this gateway */ | |
474 value.os.data = fd_g_config->cnf_diamrlm; | |
475 value.os.len = fd_g_config->cnf_diamrlm_len; | |
476 } else { | |
477 value.os.data = un + idx; | |
478 value.os.len = un_len - idx; | |
479 } | |
480 CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); | |
481 CHECK_FCT( fd_msg_avp_add ( *diam_fw, *session ? MSG_BRW_LAST_CHILD : MSG_BRW_FIRST_CHILD, avp) ); | |
482 | |
453 /* Create the Session-Id AVP if needed */ | 483 /* Create the Session-Id AVP if needed */ |
454 if (!*session) { | 484 if (!*session) { |
455 CHECK_FCT( fd_sess_fromsid ( si, si_len, session, NULL) ); | 485 CHECK_FCT( fd_sess_fromsid ( si, si_len, session, NULL) ); |
456 | 486 |
457 TRACE_DEBUG(FULL, "[auth.rgwx] Translating new accounting message for session '%.*s'...", si_len, si); | 487 TRACE_DEBUG(FULL, "[auth.rgwx] Translating new accounting message for session '%.*s'...", si_len, si); |
461 value.os.data = (unsigned char *)si; | 491 value.os.data = (unsigned char *)si; |
462 value.os.len = si_len; | 492 value.os.len = si_len; |
463 CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); | 493 CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); |
464 CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) ); | 494 CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) ); |
465 } | 495 } |
496 | |
466 | 497 |
467 /* Add the command code */ | 498 /* Add the command code */ |
468 { | 499 { |
469 struct msg_hdr * header = NULL; | 500 struct msg_hdr * header = NULL; |
470 CHECK_FCT( fd_msg_hdr ( *diam_fw, &header ) ); | 501 CHECK_FCT( fd_msg_hdr ( *diam_fw, &header ) ); |