diff --git a/lib/database.py b/lib/database.py index e338c15..90ad440 100755 --- a/lib/database.py +++ b/lib/database.py @@ -1455,8 +1455,8 @@ def Get_Served_IMS_Subscribers(self, get_local_users_only=False): IMS_SUBSCRIBER.scscf.isnot(None)) for result in results: result = result.__dict__ - self.logTool.log(service='Database', level='debug', message="Result: " + str(result, redisClient=self.redisMessaging) + - " type: " + str(type(result))) + self.logTool.log(service='Database', level='debug', message="Result: " + str(result) + + " type: " + str(type(result)), redisClient=self.redisMessaging) result = self.Sanitize_Datetime(result) result.pop('_sa_instance_state') if get_local_users_only == True: diff --git a/lib/diameter.py b/lib/diameter.py index 3df733c..8a550ce 100644 --- a/lib/diameter.py +++ b/lib/diameter.py @@ -151,21 +151,37 @@ def Reverse(self, str): def DecodePLMN(self, plmn): self.logTool.log(service='HSS', level='debug', message="Decoded PLMN: " + str(plmn), redisClient=self.redisMessaging) - mcc = self.Reverse(plmn[0:2]) + self.Reverse(plmn[2:4]).replace('f', '') - self.logTool.log(service='HSS', level='debug', message="Decoded MCC: " + mcc, redisClient=self.redisMessaging) - - mnc = self.Reverse(plmn[4:6]) - self.logTool.log(service='HSS', level='debug', message="Decoded MNC: " + mnc, redisClient=self.redisMessaging) + tvb = bytes.fromhex(plmn) + mcc1 = tvb[0] & 0xf + mcc2 = tvb[0] >> 4 + mcc3 = tvb[1] & 0xf + mcc = mcc1 * 100 + mcc2 * 10 + mcc3 + self.logTool.log(service='HSS', level='debug', message="Decoded MCC: " + str(mcc), redisClient=self.redisMessaging) + mnc3 = tvb[1] >> 4 + mnc1 = tvb[2] >> 4 + mnc2 = tvb[2] & 0xf + mnc = 10 * mnc2 + mnc1 + if mnc3 != 0xf: + mnc = mnc2 * 100 + mnc1 * 10 + mnc3 + self.logTool.log(service='HSS', level='debug', message="Decoded MNC: " + str(mnc), redisClient=self.redisMessaging) return mcc, mnc def EncodePLMN(self, mcc, mnc): plmn = list('XXXXXX') - plmn[0] = self.Reverse(mcc)[1] - plmn[1] = self.Reverse(mcc)[2] - plmn[2] = "f" - plmn[3] = self.Reverse(mcc)[0] - plmn[4] = self.Reverse(mnc)[0] - plmn[5] = self.Reverse(mnc)[1] + if len(mnc) == 2: + plmn[0] = self.Reverse(mcc)[1] + plmn[1] = self.Reverse(mcc)[2] + plmn[2] = "f" + plmn[3] = self.Reverse(mcc)[0] + plmn[4] = self.Reverse(mnc)[0] + plmn[5] = self.Reverse(mnc)[1] + else: + plmn[0] = self.Reverse(mcc)[1] + plmn[1] = self.Reverse(mcc)[2] + plmn[2] = self.Reverse(mnc)[0] + plmn[3] = self.Reverse(mcc)[0] + plmn[4] = self.Reverse(mnc)[1] + plmn[5] = self.Reverse(mnc)[2] plmn_list = plmn plmn = '' for bits in plmn_list: @@ -1282,14 +1298,17 @@ def Answer_16777251_316(self, packet_vars, avps): decodedPlmn = self.DecodePLMN(plmn=plmn) mcc = decodedPlmn[0] mnc = decodedPlmn[1] + subscriberIsRoaming = False + subscriberRoamingAllowed = False + if str(mcc) != str(self.MCC) and str(mnc) != str(self.MNC): subscriberIsRoaming = True if subscriberIsRoaming: - self.logTool.log(service='HSS', level='debug', message=f"[diameter.py] [Answer_16777251_318] [AIA] Subscriber {imsi} is roaming", redisClient=self.redisMessaging) + self.logTool.log(service='HSS', level='debug', message=f"[diameter.py] [Answer_16777251_318] [ULA] Subscriber {imsi} is roaming", redisClient=self.redisMessaging) subscriberRoamingAllowed = self.validateSubscriberRoaming(subscriber=subscriber_details, mcc=mcc, mnc=mnc) - if not subscriberRoamingAllowed: + if not subscriberRoamingAllowed and subscriberIsRoaming: avp = '' session_id = self.get_avp_data(avps, 263)[0] #Get Session-ID avp += self.generate_avp(263, 40, session_id) #Session-ID AVP set @@ -1608,6 +1627,9 @@ def Answer_16777251_318(self, packet_vars, avps): decodedPlmn = self.DecodePLMN(plmn=plmn) mcc = decodedPlmn[0] mnc = decodedPlmn[1] + subscriberIsRoaming=False + subscriberRoamingAllowed=False + if str(mcc) != str(self.MCC) and str(mnc) != str(self.MNC): subscriberIsRoaming = True @@ -1615,7 +1637,7 @@ def Answer_16777251_318(self, packet_vars, avps): self.logTool.log(service='HSS', level='debug', message=f"[diameter.py] [Answer_16777251_318] [AIA] Subscriber {imsi} is roaming", redisClient=self.redisMessaging) subscriberRoamingAllowed = self.validateSubscriberRoaming(subscriber=subscriber_details, mcc=mcc, mnc=mnc) - if not subscriberRoamingAllowed: + if not subscriberRoamingAllowed and subscriberIsRoaming: avp = '' session_id = self.get_avp_data(avps, 263)[0] #Get Session-ID avp += self.generate_avp(263, 40, session_id) #Session-ID AVP set @@ -2545,9 +2567,30 @@ def Answer_16777236_265(self, packet_vars, avps): msisdn = imsSubscriberDetails.get('msisdn', None) except Exception as e: pass + if identifier == None: + try: + ueIP = subscriptionId.split('@')[1].split(':')[0] + ue = self.database.Get_UE_by_IP(ueIP) + subId = ue.get('subscriber_id', None) + subscriberDetails = self.database.Get_Subscriber(subscriber_id=subId) + imsi = subscriberDetails.get('imsi', None) + self.logTool.log(service='HSS', level='debug', message=f"[diameter.py] [Answer_16777236_265] [AAA] Found IMSI {imsi} by IP: {ueIP}", redisClient=self.redisMessaging) + except Exception as e: + pass else: imsi = None msisdn = None + try: + ueIP = subscriptionId.split(':')[0] + ue = self.database.Get_UE_by_IP(ueIP) + subId = ue.get('subscriber_id', None) + subscriberDetails = self.database.Get_Subscriber(subscriber_id=subId) + imsi = subscriberDetails.get('imsi', None) + self.logTool.log(service='HSS', level='debug', message=f"[diameter.py] [Answer_16777236_265] [AAA] Found IMSI {imsi} by IP: {ueIP}", redisClient=self.redisMessaging) + except Exception as e: + pass + + self.logTool.log(service='HSS', level='debug', message=f"[diameter.py] [Answer_16777236_265] [AAA] IMSI: {imsi}\nMSISDN: {msisdn}", redisClient=self.redisMessaging) imsEnabled = self.validateImsSubscriber(imsi=imsi, msisdn=msisdn) @@ -2649,6 +2692,18 @@ def Answer_16777236_265(self, packet_vars, avps): "direction": 2, "tft_id": 2, "tft_string": "permit out 17 from {{ UE_IP }}/32 1-65535 to any 1-65535" + }, + { + "tft_group_id": 1, + "direction": 1, + "tft_id": 3, + "tft_string": "permit out 17 from any to {{ UE_IP }} 1-65535" + }, + { + "tft_group_id": 1, + "direction": 2, + "tft_id": 4, + "tft_string": "permit out 17 from any to {{ UE_IP }} 1-65535" } ] } diff --git a/services/apiService.py b/services/apiService.py index 2fba9d2..2949cad 100644 --- a/services/apiService.py +++ b/services/apiService.py @@ -130,12 +130,10 @@ #Legacy support for sh_profile. sh_profile is deprecated as of v1.0.1. -imsSubscriberModel = databaseClient.Generate_JSON_Model_for_Flask(TFT) +imsSubscriberModel = databaseClient.Generate_JSON_Model_for_Flask(IMS_SUBSCRIBER) imsSubscriberModel['sh_profile'] = fields.String(required=False, description=IMS_SUBSCRIBER.sh_profile.doc), -IMS_SUBSCRIBER_model = api.schema_model('IMS_SUBSCRIBER JSON', - databaseClient.Generate_JSON_Model_for_Flask(TFT) -) +IMS_SUBSCRIBER_model = api.schema_model('IMS_SUBSCRIBER JSON', databaseClient.Generate_JSON_Model_for_Flask(IMS_SUBSCRIBER)) TFT_model = api.schema_model('TFT JSON', databaseClient.Generate_JSON_Model_for_Flask(TFT) @@ -1818,6 +1816,7 @@ def get(self, charging_rule_id): print(E) return handle_exception(E) + @ns_pcrf.route('/subscriber_routing/') class PyHSS_PCRF_SUBSCRIBER_ROUTING(Resource): def get(self, subscriber_routing):