Pau Espin Pedrol | a469a90 | 2019-05-31 15:37:50 +0200 | [diff] [blame] | 1 | /* |
Harald Welte | 632e843 | 2017-09-05 18:12:14 +0200 | [diff] [blame] | 2 | * OsmoGGSN - Gateway GPRS Support Node |
jjako | 0fe0df0 | 2004-09-17 11:30:40 +0000 | [diff] [blame] | 3 | * Copyright (C) 2002, 2003, 2004 Mondru AB. |
Pau Espin Pedrol | a469a90 | 2019-05-31 15:37:50 +0200 | [diff] [blame] | 4 | * |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 5 | * The contents of this file may be used under the terms of the GNU |
| 6 | * General Public License Version 2, provided that the above copyright |
| 7 | * notice and this permission notice is included in all copies or |
| 8 | * substantial portions of the software. |
Pau Espin Pedrol | a469a90 | 2019-05-31 15:37:50 +0200 | [diff] [blame] | 9 | * |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 10 | */ |
| 11 | |
| 12 | #ifndef _GTP_H |
| 13 | #define _GTP_H |
| 14 | |
Max | e661277 | 2018-01-11 18:25:37 +0100 | [diff] [blame] | 15 | #include <osmocom/core/utils.h> |
Pau Espin Pedrol | 8e8c7ef | 2018-07-16 16:47:12 +0200 | [diff] [blame] | 16 | #include <osmocom/core/defs.h> |
Pau Espin Pedrol | c94837c | 2019-08-28 19:44:20 +0200 | [diff] [blame] | 17 | #include <osmocom/core/timer.h> |
Max | e661277 | 2018-01-11 18:25:37 +0100 | [diff] [blame] | 18 | |
Pau Espin Pedrol | eefa30d | 2019-05-31 15:42:49 +0200 | [diff] [blame] | 19 | #include "pdp.h" |
| 20 | |
jjako | 1db1c81 | 2003-07-06 20:53:57 +0000 | [diff] [blame] | 21 | #define GTP_MODE_GGSN 1 |
| 22 | #define GTP_MODE_SGSN 2 |
| 23 | |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 24 | #define GTP0_PORT 3386 |
| 25 | #define GTP1C_PORT 2123 |
| 26 | #define GTP1U_PORT 2152 |
| 27 | #define PACKET_MAX 8196 |
| 28 | |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 29 | #define GTP_MAX 0xffff /* TODO: Choose right number */ |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 30 | #define GTP0_HEADER_SIZE 20 |
| 31 | #define GTP1_HEADER_SIZE_SHORT 8 |
| 32 | #define GTP1_HEADER_SIZE_LONG 12 |
| 33 | |
| 34 | #define SYSLOG_PRINTSIZE 255 |
| 35 | #define ERRMSG_SIZE 255 |
| 36 | |
| 37 | #define RESTART_FILE "gsn_restart" |
| 38 | #define NAMESIZE 1024 |
| 39 | |
jjako | 2c38133 | 2003-10-21 19:09:53 +0000 | [diff] [blame] | 40 | /* GTP version 1 extension header type definitions. */ |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 41 | #define GTP_EXT_PDCP_PDU 0xC0 /* PDCP PDU Number */ |
jjako | 2c38133 | 2003-10-21 19:09:53 +0000 | [diff] [blame] | 42 | |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 43 | /* GTP version 1 message type definitions. Also covers version 0 except * |
| 44 | * for anonymous PDP context which was superceded in version 1 */ |
| 45 | |
| 46 | /* 0 For future use. */ |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 47 | #define GTP_ECHO_REQ 1 /* Echo Request */ |
| 48 | #define GTP_ECHO_RSP 2 /* Echo Response */ |
| 49 | #define GTP_NOT_SUPPORTED 3 /* Version Not Supported */ |
| 50 | #define GTP_ALIVE_REQ 4 /* Node Alive Request */ |
| 51 | #define GTP_ALIVE_RSP 5 /* Node Alive Response */ |
| 52 | #define GTP_REDIR_REQ 6 /* Redirection Request */ |
| 53 | #define GTP_REDIR_RSP 7 /* Redirection Response */ |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 54 | /* 8-15 For future use. */ |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 55 | #define GTP_CREATE_PDP_REQ 16 /* Create PDP Context Request */ |
| 56 | #define GTP_CREATE_PDP_RSP 17 /* Create PDP Context Response */ |
| 57 | #define GTP_UPDATE_PDP_REQ 18 /* Update PDP Context Request */ |
| 58 | #define GTP_UPDATE_PDP_RSP 19 /* Update PDP Context Response */ |
| 59 | #define GTP_DELETE_PDP_REQ 20 /* Delete PDP Context Request */ |
| 60 | #define GTP_DELETE_PDP_RSP 21 /* Delete PDP Context Response */ |
| 61 | /* 22-25 For future use. *//* In version GTP 1 anonomous PDP context */ |
| 62 | #define GTP_ERROR 26 /* Error Indication */ |
| 63 | #define GTP_PDU_NOT_REQ 27 /* PDU Notification Request */ |
| 64 | #define GTP_PDU_NOT_RSP 28 /* PDU Notification Response */ |
| 65 | #define GTP_PDU_NOT_REJ_REQ 29 /* PDU Notification Reject Request */ |
| 66 | #define GTP_PDU_NOT_REJ_RSP 30 /* PDU Notification Reject Response */ |
| 67 | #define GTP_SUPP_EXT_HEADER 31 /* Supported Extension Headers Notification */ |
| 68 | #define GTP_SND_ROUTE_REQ 32 /* Send Routeing Information for GPRS Request */ |
| 69 | #define GTP_SND_ROUTE_RSP 33 /* Send Routeing Information for GPRS Response */ |
| 70 | #define GTP_FAILURE_REQ 34 /* Failure Report Request */ |
| 71 | #define GTP_FAILURE_RSP 35 /* Failure Report Response */ |
| 72 | #define GTP_MS_PRESENT_REQ 36 /* Note MS GPRS Present Request */ |
| 73 | #define GTP_MS_PRESENT_RSP 37 /* Note MS GPRS Present Response */ |
| 74 | /* 38-47 For future use. */ |
| 75 | #define GTP_IDEN_REQ 48 /* Identification Request */ |
| 76 | #define GTP_IDEN_RSP 49 /* Identification Response */ |
| 77 | #define GTP_SGSN_CONTEXT_REQ 50 /* SGSN Context Request */ |
| 78 | #define GTP_SGSN_CONTEXT_RSP 51 /* SGSN Context Response */ |
| 79 | #define GTP_SGSN_CONTEXT_ACK 52 /* SGSN Context Acknowledge */ |
| 80 | #define GTP_FWD_RELOC_REQ 53 /* Forward Relocation Request */ |
| 81 | #define GTP_FWD_RELOC_RSP 54 /* Forward Relocation Response */ |
| 82 | #define GTP_FWD_RELOC_COMPL 55 /* Forward Relocation Complete */ |
| 83 | #define GTP_RELOC_CANCEL_REQ 56 /* Relocation Cancel Request */ |
| 84 | #define GTP_RELOC_CANCEL_RSP 57 /* Relocation Cancel Response */ |
| 85 | #define GTP_FWD_SRNS 58 /* Forward SRNS Context */ |
| 86 | #define GTP_FWD_RELOC_ACK 59 /* Forward Relocation Complete Acknowledge */ |
| 87 | #define GTP_FWD_SRNS_ACK 60 /* Forward SRNS Context Acknowledge */ |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 88 | /* 61-239 For future use. */ |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 89 | #define GTP_DATA_TRAN_REQ 240 /* Data Record Transfer Request */ |
| 90 | #define GTP_DATA_TRAN_RSP 241 /* Data Record Transfer Response */ |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 91 | /* 242-254 For future use. */ |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 92 | #define GTP_GPDU 255 /* G-PDU */ |
jjako | 08d331d | 2003-10-13 20:33:30 +0000 | [diff] [blame] | 93 | |
Max | e661277 | 2018-01-11 18:25:37 +0100 | [diff] [blame] | 94 | extern const struct value_string gtp_type_names[]; |
| 95 | static inline const char *gtp_type_name(uint8_t val) |
| 96 | { return get_value_string(gtp_type_names, val); } |
| 97 | |
jjako | 08d331d | 2003-10-13 20:33:30 +0000 | [diff] [blame] | 98 | /* GTP information element cause codes from 29.060 v3.9.0 7.7 */ |
| 99 | /* */ |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 100 | #define GTPCAUSE_REQ_IMSI 0 /* Request IMSI */ |
| 101 | #define GTPCAUSE_REQ_IMEI 1 /* Request IMEI */ |
| 102 | #define GTPCAUSE_REQ_IMSI_IMEI 2 /* Request IMSI and IMEI */ |
| 103 | #define GTPCAUSE_NO_ID_NEEDED 3 /* No identity needed */ |
| 104 | #define GTPCAUSE_MS_REFUSES_X 4 /* MS refuses */ |
| 105 | #define GTPCAUSE_MS_NOT_RESP_X 5 /* MS is not GPRS responding */ |
| 106 | #define GTPCAUSE_006 6 /* For future use 6-48 */ |
| 107 | #define GTPCAUSE_049 49 /* Cause values reserved for GPRS charging protocol use (See GTP' in GSM 12.15) 49-63 */ |
| 108 | #define GTPCAUSE_064 64 /* For future use 64-127 */ |
| 109 | #define GTPCAUSE_ACC_REQ 128 /* Request accepted */ |
| 110 | #define GTPCAUSE_129 129 /* For future use 129-176 */ |
| 111 | #define GTPCAUSE_177 177 /* Cause values reserved for GPRS charging protocol use (See GTP' In GSM 12.15) 177-191 */ |
| 112 | #define GTPCAUSE_NON_EXIST 192 /* Non-existent */ |
| 113 | #define GTPCAUSE_INVALID_MESSAGE 193 /* Invalid message format */ |
| 114 | #define GTPCAUSE_IMSI_NOT_KNOWN 194 /* IMSI not known */ |
| 115 | #define GTPCAUSE_MS_DETACHED 195 /* MS is GPRS detached */ |
| 116 | #define GTPCAUSE_MS_NOT_RESP 196 /* MS is not GPRS responding */ |
| 117 | #define GTPCAUSE_MS_REFUSES 197 /* MS refuses */ |
| 118 | #define GTPCAUSE_198 198 /* For future use */ |
| 119 | #define GTPCAUSE_NO_RESOURCES 199 /* No resources available */ |
| 120 | #define GTPCAUSE_NOT_SUPPORTED 200 /* Service not supported */ |
| 121 | #define GTPCAUSE_MAN_IE_INCORRECT 201 /* Mandatory IE incorrect */ |
| 122 | #define GTPCAUSE_MAN_IE_MISSING 202 /* Mandatory IE missing */ |
| 123 | #define GTPCAUSE_OPT_IE_INCORRECT 203 /* Optional IE incorrect */ |
| 124 | #define GTPCAUSE_SYS_FAIL 204 /* System failure */ |
| 125 | #define GTPCAUSE_ROAMING_REST 205 /* Roaming Restriction */ |
| 126 | #define GTPCAUSE_PTIMSI_MISMATCH 206 /* P-TMSI signature mismatch */ |
| 127 | #define GTPCAUSE_CONN_SUSP 207 /* GPRS connection suspended */ |
| 128 | #define GTPCAUSE_AUTH_FAIL 208 /* Authentication failure */ |
| 129 | #define GTPCAUSE_USER_AUTH_FAIL 209 /* User authentication failed */ |
| 130 | #define GTPCAUSE_CONTEXT_NOT_FOUND 210 /* Context not found */ |
| 131 | #define GTPCAUSE_ADDR_OCCUPIED 211 /* All dynamic PDP addresses are occupied */ |
| 132 | #define GTPCAUSE_NO_MEMORY 212 /* No memory is available */ |
| 133 | #define GTPCAUSE_RELOC_FAIL 213 /* Relocation failure */ |
| 134 | #define GTPCAUSE_UNKNOWN_MAN_EXTHEADER 214 /* Unknown mandatory extension header */ |
| 135 | #define GTPCAUSE_SEM_ERR_TFT 215 /* Semantic error in the TFT operation */ |
| 136 | #define GTPCAUSE_SYN_ERR_TFT 216 /* Syntactic error in the TFT operation */ |
| 137 | #define GTPCAUSE_SEM_ERR_FILTER 217 /* Semantic errors in packet filter(s) */ |
| 138 | #define GTPCAUSE_SYN_ERR_FILTER 218 /* Syntactic errors in packet filter(s) */ |
| 139 | #define GTPCAUSE_MISSING_APN 219 /* Missing or unknown APN */ |
| 140 | #define GTPCAUSE_UNKNOWN_PDP 220 /* Unknown PDP address or PDP type */ |
| 141 | #define GTPCAUSE_221 221 /* For Future Use 221-240 */ |
| 142 | #define GTPCAUSE_241 241 /* Cause Values Reserved For Gprs Charging Protocol Use (See Gtp' In Gsm 12.15) 241-255 */ |
jjako | 08d331d | 2003-10-13 20:33:30 +0000 | [diff] [blame] | 143 | |
Holger Hans Peter Freyther | 0382996 | 2013-07-27 20:01:15 +0200 | [diff] [blame] | 144 | struct ul66_t; |
| 145 | struct ul16_t; |
Holger Hans Peter Freyther | 3a9befb | 2016-01-23 10:15:43 +0100 | [diff] [blame] | 146 | struct pdp_t; |
Holger Hans Peter Freyther | 0382996 | 2013-07-27 20:01:15 +0200 | [diff] [blame] | 147 | |
Pau Espin Pedrol | a469a90 | 2019-05-31 15:37:50 +0200 | [diff] [blame] | 148 | /* GTP 0 header. |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 149 | * Explanation to some of the fields: |
| 150 | * SNDCP NPDU Number flag = 0 except for inter SGSN handover situations |
| 151 | * SNDCP N-PDU LCC Number 0 = 0xff except for inter SGSN handover situations |
| 152 | * Sequence number. Used for reliable delivery of signalling messages, and |
| 153 | * to discard "illegal" data messages. |
| 154 | * Flow label. Is used to point a particular PDP context. Is used in data |
| 155 | * messages as well as signalling messages related to a particular context. |
| 156 | * Tunnel ID is IMSI+NSAPI. Unique identifier of PDP context. Is somewhat |
| 157 | * redundant because the header also includes flow. */ |
| 158 | |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 159 | struct gtp0_header { /* Descriptions from 3GPP 09.60 */ |
| 160 | uint8_t flags; /* 01 bitfield, with typical values */ |
| 161 | /* 000..... Version: 1 (0) */ |
| 162 | /* ...1111. Spare (7) */ |
| 163 | /* .......0 SNDCP N-PDU Number flag (0) */ |
| 164 | uint8_t type; /* 02 Message type. T-PDU = 0xff */ |
| 165 | uint16_t length; /* 03 Length (of G-PDU excluding header) */ |
| 166 | uint16_t seq; /* 05 Sequence Number */ |
| 167 | uint16_t flow; /* 07 Flow Label ( = 0 for signalling) */ |
| 168 | uint8_t number; /* 09 SNDCP N-PDU LCC Number ( 0 = 0xff) */ |
| 169 | uint8_t spare1; /* 10 Spare */ |
| 170 | uint8_t spare2; /* 11 Spare */ |
| 171 | uint8_t spare3; /* 12 Spare */ |
| 172 | uint64_t tid; /* 13 Tunnel ID */ |
Pablo Neira Ayuso | 0674f0b | 2014-03-19 22:55:29 +0100 | [diff] [blame] | 173 | } __attribute__((packed)); /* 20 */ |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 174 | |
Harald Welte | fed598f | 2017-09-24 16:39:22 +0800 | [diff] [blame] | 175 | #define GTP1HDR_F_NPDU 0x01 |
| 176 | #define GTP1HDR_F_SEQ 0x02 |
| 177 | #define GTP1HDR_F_EXT 0x04 |
| 178 | #define GTP1HDR_F_GTP1 0x10 |
| 179 | #define GTPHDR_F_VER(n) ((n) << 5) |
| 180 | #define GTPHDR_F_GET_VER(flags) ((flags)>>5) |
| 181 | |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 182 | struct gtp1_header_short { /* Descriptions from 3GPP 29060 */ |
| 183 | uint8_t flags; /* 01 bitfield, with typical values */ |
| 184 | /* 001..... Version: 1 */ |
| 185 | /* ...1.... Protocol Type: GTP=1, GTP'=0 */ |
| 186 | /* ....0... Spare = 0 */ |
| 187 | /* .....0.. Extension header flag: 0 */ |
| 188 | /* ......0. Sequence number flag: 0 */ |
| 189 | /* .......0 PN: N-PDU Number flag */ |
| 190 | uint8_t type; /* 02 Message type. T-PDU = 0xff */ |
| 191 | uint16_t length; /* 03 Length (of IP packet or signalling) */ |
| 192 | uint32_t tei; /* 05 - 08 Tunnel Endpoint ID */ |
Pablo Neira Ayuso | 0674f0b | 2014-03-19 22:55:29 +0100 | [diff] [blame] | 193 | } __attribute__((packed)); |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 194 | |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 195 | struct gtp1_header_long { /* Descriptions from 3GPP 29060 */ |
| 196 | uint8_t flags; /* 01 bitfield, with typical values */ |
| 197 | /* 001..... Version: 1 */ |
| 198 | /* ...1.... Protocol Type: GTP=1, GTP'=0 */ |
| 199 | /* ....0... Spare = 0 */ |
| 200 | /* .....0.. Extension header flag: 0 */ |
| 201 | /* ......1. Sequence number flag: 1 */ |
| 202 | /* .......0 PN: N-PDU Number flag */ |
| 203 | uint8_t type; /* 02 Message type. T-PDU = 0xff */ |
| 204 | uint16_t length; /* 03 Length (of IP packet or signalling) */ |
| 205 | uint32_t tei; /* 05 Tunnel Endpoint ID */ |
| 206 | uint16_t seq; /* 10 Sequence Number */ |
| 207 | uint8_t npdu; /* 11 N-PDU Number */ |
| 208 | uint8_t next; /* 12 Next extension header type. Empty = 0 */ |
Pablo Neira Ayuso | 0674f0b | 2014-03-19 22:55:29 +0100 | [diff] [blame] | 209 | } __attribute__((packed)); |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 210 | |
| 211 | struct gtp0_packet { |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 212 | struct gtp0_header h; |
| 213 | uint8_t p[GTP_MAX]; |
| 214 | } __attribute__ ((packed)); |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 215 | |
| 216 | struct gtp1_packet_short { |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 217 | struct gtp1_header_short h; |
| 218 | uint8_t p[GTP_MAX]; |
| 219 | } __attribute__ ((packed)); |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 220 | |
| 221 | struct gtp1_packet_long { |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 222 | struct gtp1_header_long h; |
| 223 | uint8_t p[GTP_MAX]; |
| 224 | } __attribute__ ((packed)); |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 225 | |
| 226 | union gtp_packet { |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 227 | uint8_t flags; |
| 228 | struct gtp0_packet gtp0; |
| 229 | struct gtp1_packet_short gtp1s; |
| 230 | struct gtp1_packet_long gtp1l; |
| 231 | } __attribute__ ((packed)); |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 232 | |
| 233 | /* *********************************************************** |
| 234 | * Information storage for each gsn instance |
| 235 | * |
| 236 | * Normally each instance of the application corresponds to |
Pau Espin Pedrol | a469a90 | 2019-05-31 15:37:50 +0200 | [diff] [blame] | 237 | * one instance of a gsn. |
| 238 | * |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 239 | * In order to avoid global variables in the application, and |
| 240 | * also in order to allow several instances of a gsn in the same |
| 241 | * application this struct is provided in order to store all |
| 242 | * relevant information related to the gsn. |
Pau Espin Pedrol | a469a90 | 2019-05-31 15:37:50 +0200 | [diff] [blame] | 243 | * |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 244 | * Note that this does not include information storage for ' |
| 245 | * each pdp context. This is stored in another struct. |
| 246 | *************************************************************/ |
| 247 | |
| 248 | struct gsn_t { |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 249 | /* Parameters related to the network interface */ |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 250 | |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 251 | int fd0; /* GTP0 file descriptor */ |
| 252 | int fd1c; /* GTP1 control plane file descriptor */ |
| 253 | int fd1u; /* GTP0 user plane file descriptor */ |
| 254 | int mode; /* Mode of operation: GGSN or SGSN */ |
| 255 | struct in_addr gsnc; /* IP address of this gsn for signalling */ |
| 256 | struct in_addr gsnu; /* IP address of this gsn for user traffic */ |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 257 | |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 258 | /* Parameters related to signalling messages */ |
| 259 | uint16_t seq_next; /* Next sequence number to use */ |
| 260 | int seq_first; /* First packet in queue (oldest timeout) */ |
| 261 | int seq_last; /* Last packet in queue (youngest timeout) */ |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 262 | |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 263 | unsigned char restart_counter; /* Increment on restart. Stored on disk */ |
| 264 | char *statedir; /* Disk location for permanent storage */ |
Harald Welte | 8a03ea8 | 2017-08-12 14:52:45 +0200 | [diff] [blame] | 265 | void *priv; /* used by libgtp users to attach their own state) */ |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 266 | struct queue_t *queue_req; /* Request queue */ |
| 267 | struct queue_t *queue_resp; /* Response queue */ |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 268 | |
Pau Espin Pedrol | eefa30d | 2019-05-31 15:42:49 +0200 | [diff] [blame] | 269 | struct pdp_t pdpa[PDP_MAX]; /* PDP storage */ |
| 270 | struct pdp_t *hashtid[PDP_MAX]; /* Hash table for IMSI + NSAPI */ |
| 271 | |
Pau Espin Pedrol | c94837c | 2019-08-28 19:44:20 +0200 | [diff] [blame] | 272 | struct osmo_timer_list queue_timer; /* internal queue_{req,resp} timer */ |
| 273 | |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 274 | /* Call back functions */ |
| 275 | int (*cb_delete_context) (struct pdp_t *); |
| 276 | int (*cb_create_context_ind) (struct pdp_t *); |
| 277 | int (*cb_unsup_ind) (struct sockaddr_in * peer); |
| 278 | int (*cb_extheader_ind) (struct sockaddr_in * peer); |
| 279 | int (*cb_conf) (int type, int cause, struct pdp_t * pdp, void *cbp); |
| 280 | int (*cb_data_ind) (struct pdp_t * pdp, void *pack, unsigned len); |
| 281 | int (*cb_recovery) (struct sockaddr_in * peer, uint8_t recovery); |
Pau Espin Pedrol | b5f9334 | 2018-07-23 11:24:07 +0200 | [diff] [blame] | 282 | int (*cb_recovery2) (struct sockaddr_in * peer, struct pdp_t * pdp, uint8_t recovery); |
Pau Espin Pedrol | 5d8b226 | 2019-08-22 15:00:00 +0200 | [diff] [blame] | 283 | int (*cb_recovery3) (struct gsn_t *gsn, struct sockaddr_in *peer, struct pdp_t *pdp, uint8_t recovery); |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 284 | |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 285 | /* Counters */ |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 286 | |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 287 | uint64_t err_socket; /* Number of socket errors */ |
| 288 | uint64_t err_readfrom; /* Number of readfrom errors */ |
| 289 | uint64_t err_sendto; /* Number of sendto errors */ |
| 290 | uint64_t err_memcpy; /* Number of memcpy */ |
| 291 | uint64_t err_queuefull; /* Number of times queue was full */ |
| 292 | uint64_t err_seq; /* Number of seq out of range */ |
| 293 | uint64_t err_address; /* GSN address conversion failed */ |
| 294 | uint64_t err_unknownpdp; /* GSN address conversion failed */ |
| 295 | uint64_t err_unknowntid; /* Application supplied unknown imsi+nsapi */ |
| 296 | uint64_t err_cause; /* Unexpected cause value received */ |
| 297 | uint64_t err_outofpdp; /* Out of storage for PDP contexts */ |
| 298 | |
| 299 | uint64_t empty; /* Number of empty packets */ |
| 300 | uint64_t unsup; /* Number of unsupported version 29.60 11.1.1 */ |
| 301 | uint64_t tooshort; /* Number of too short headers 29.60 11.1.2 */ |
| 302 | uint64_t unknown; /* Number of unknown messages 29.60 11.1.3 */ |
| 303 | uint64_t unexpect; /* Number of unexpected messages 29.60 11.1.4 */ |
Neels Hofmeyr | b18e811 | 2015-10-12 14:00:21 +0200 | [diff] [blame] | 304 | uint64_t duplicate; /* Number of duplicate or unsolicited replies */ |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 305 | uint64_t missing; /* Number of missing information field messages */ |
| 306 | uint64_t incorrect; /* Number of incorrect information field messages */ |
| 307 | uint64_t invalid; /* Number of invalid message format messages */ |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 308 | }; |
| 309 | |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 310 | /* External API functions */ |
| 311 | |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 312 | extern const char *gtp_version(); |
jjako | 1db1c81 | 2003-07-06 20:53:57 +0000 | [diff] [blame] | 313 | extern int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen, |
| 314 | int mode); |
| 315 | |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 316 | extern int gtp_free(struct gsn_t *gsn); |
| 317 | |
| 318 | extern int gtp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp, |
Pau Espin Pedrol | eefa30d | 2019-05-31 15:42:49 +0200 | [diff] [blame] | 319 | uint64_t imsi, uint8_t nsapi) OSMO_DEPRECATED("Use gtp_pdp_newpdp() instead"); |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 320 | extern int gtp_freepdp(struct gsn_t *gsn, struct pdp_t *pdp); |
Pau Espin Pedrol | 0d0b059 | 2019-05-29 20:42:09 +0200 | [diff] [blame] | 321 | extern int gtp_freepdp_teardown(struct gsn_t *gsn, struct pdp_t *pdp); |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 322 | |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 323 | extern int gtp_create_context_req(struct gsn_t *gsn, struct pdp_t *pdp, |
jjako | 193e8b1 | 2003-11-10 12:31:41 +0000 | [diff] [blame] | 324 | void *cbp); |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 325 | |
jjako | 08d331d | 2003-10-13 20:33:30 +0000 | [diff] [blame] | 326 | extern int gtp_set_cb_create_context_ind(struct gsn_t *gsn, |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 327 | int (*cb_create_context_ind) (struct |
| 328 | pdp_t * |
| 329 | pdp)); |
jjako | 1db1c81 | 2003-07-06 20:53:57 +0000 | [diff] [blame] | 330 | |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 331 | extern int gtp_create_context_resp(struct gsn_t *gsn, struct pdp_t *pdp, |
jjako | 08d331d | 2003-10-13 20:33:30 +0000 | [diff] [blame] | 332 | int cause); |
| 333 | |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 334 | extern int gtp_update_context(struct gsn_t *gsn, struct pdp_t *pdp, |
| 335 | void *cbp, struct in_addr *inetaddr); |
jjako | 08d331d | 2003-10-13 20:33:30 +0000 | [diff] [blame] | 336 | |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 337 | extern int gtp_delete_context_req(struct gsn_t *gsn, struct pdp_t *pdp, |
Pau Espin Pedrol | 8e8c7ef | 2018-07-16 16:47:12 +0200 | [diff] [blame] | 338 | void *cbp, int teardown) |
| 339 | OSMO_DEPRECATED("Use gtp_delete_context_req2() instead, to avoid freeing pdp ctx before reply"); |
| 340 | extern int gtp_delete_context_req2(struct gsn_t *gsn, struct pdp_t *pdp, |
| 341 | void *cbp, int teardown); |
jjako | 08d331d | 2003-10-13 20:33:30 +0000 | [diff] [blame] | 342 | |
| 343 | extern int gtp_data_req(struct gsn_t *gsn, struct pdp_t *pdp, |
| 344 | void *pack, unsigned len); |
| 345 | |
| 346 | extern int gtp_set_cb_data_ind(struct gsn_t *gsn, |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 347 | int (*cb_data_ind) (struct pdp_t * pdp, |
| 348 | void *pack, unsigned len)); |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 349 | |
| 350 | extern int gtp_fd(struct gsn_t *gsn); |
jjako | 08d331d | 2003-10-13 20:33:30 +0000 | [diff] [blame] | 351 | extern int gtp_decaps0(struct gsn_t *gsn); |
| 352 | extern int gtp_decaps1c(struct gsn_t *gsn); |
| 353 | extern int gtp_decaps1u(struct gsn_t *gsn); |
Pau Espin Pedrol | c94837c | 2019-08-28 19:44:20 +0200 | [diff] [blame] | 354 | extern int gtp_retrans(struct gsn_t *gsn) OSMO_DEPRECATED("This API is a no-op, libgtp already does the job internally"); |
| 355 | extern int gtp_retranstimeout(struct gsn_t *gsn, struct timeval *timeout) OSMO_DEPRECATED("This API is a no-op and will return a 1 day timeout"); |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 356 | |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 357 | extern int gtp_set_cb_delete_context(struct gsn_t *gsn, |
| 358 | int (*cb_delete_context) (struct pdp_t * |
| 359 | pdp)); |
jjako | 08d331d | 2003-10-13 20:33:30 +0000 | [diff] [blame] | 360 | /*extern int gtp_set_cb_create_context(struct gsn_t *gsn, |
| 361 | int (*cb_create_context) (struct pdp_t* pdp)); */ |
| 362 | |
| 363 | extern int gtp_set_cb_unsup_ind(struct gsn_t *gsn, |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 364 | int (*cb) (struct sockaddr_in * peer)); |
jjako | 08d331d | 2003-10-13 20:33:30 +0000 | [diff] [blame] | 365 | |
jjako | 2c38133 | 2003-10-21 19:09:53 +0000 | [diff] [blame] | 366 | extern int gtp_set_cb_extheader_ind(struct gsn_t *gsn, |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 367 | int (*cb) (struct sockaddr_in * peer)); |
jjako | 08d331d | 2003-10-13 20:33:30 +0000 | [diff] [blame] | 368 | |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 369 | extern int gtp_set_cb_conf(struct gsn_t *gsn, |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 370 | int (*cb) (int type, int cause, struct pdp_t * pdp, |
| 371 | void *cbp)); |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 372 | |
Harald Welte | 629e986 | 2010-12-24 20:58:09 +0100 | [diff] [blame] | 373 | int gtp_set_cb_recovery(struct gsn_t *gsn, |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 374 | int (*cb) (struct sockaddr_in * peer, |
Pau Espin Pedrol | b5f9334 | 2018-07-23 11:24:07 +0200 | [diff] [blame] | 375 | uint8_t recovery)) |
| 376 | OSMO_DEPRECATED("Use gtp_set_cb_recovery2() instead, to obtain pdp ctx originating the recovery"); |
| 377 | int gtp_set_cb_recovery2(struct gsn_t *gsn, |
| 378 | int (*cb) (struct sockaddr_in * peer, |
| 379 | struct pdp_t * pdp, |
Pau Espin Pedrol | 5d8b226 | 2019-08-22 15:00:00 +0200 | [diff] [blame] | 380 | uint8_t recovery)) |
| 381 | OSMO_DEPRECATED("Use gtp_set_cb_recovery3() instead, to obtain gsn handling the recovery");; |
| 382 | int gtp_set_cb_recovery3(struct gsn_t *gsn, |
| 383 | int (*cb) (struct gsn_t * gsn, struct sockaddr_in * peer, |
| 384 | struct pdp_t * pdp, |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 385 | uint8_t recovery)); |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 386 | |
Alexander Couzens | e1412d9 | 2018-09-16 05:10:03 +0200 | [diff] [blame] | 387 | void gtp_clear_queues(struct gsn_t *gsn); |
| 388 | |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 389 | /* Internal functions (not part of the API */ |
| 390 | |
jjako | 08d331d | 2003-10-13 20:33:30 +0000 | [diff] [blame] | 391 | extern int gtp_echo_req(struct gsn_t *gsn, int version, void *cbp, |
| 392 | struct in_addr *inetaddrs); |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 393 | extern int gtp_echo_resp(struct gsn_t *gsn, int version, |
jjako | 08d331d | 2003-10-13 20:33:30 +0000 | [diff] [blame] | 394 | struct sockaddr_in *peer, int fd, |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 395 | void *pack, unsigned len); |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 396 | extern int gtp_echo_ind(struct gsn_t *gsn, int version, |
| 397 | struct sockaddr_in *peer, int fd, |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 398 | void *pack, unsigned len); |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 399 | extern int gtp_echo_conf(struct gsn_t *gsn, int version, |
| 400 | struct sockaddr_in *peer, void *pack, unsigned len); |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 401 | |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 402 | extern int gtp_unsup_req(struct gsn_t *gsn, int version, |
jjako | 08d331d | 2003-10-13 20:33:30 +0000 | [diff] [blame] | 403 | struct sockaddr_in *peer, |
| 404 | int fd, void *pack, unsigned len); |
| 405 | extern int gtp_unsup_ind(struct gsn_t *gsn, struct sockaddr_in *peer, |
| 406 | void *pack, unsigned len); |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 407 | |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 408 | extern int gtp_create_pdp_resp(struct gsn_t *gsn, int version, |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 409 | struct pdp_t *pdp, uint8_t cause); |
| 410 | |
| 411 | extern int gtp_create_pdp_ind(struct gsn_t *gsn, int version, |
jjako | 08d331d | 2003-10-13 20:33:30 +0000 | [diff] [blame] | 412 | struct sockaddr_in *peer, int fd, |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 413 | void *pack, unsigned len); |
| 414 | |
| 415 | extern int gtp_create_pdp_conf(struct gsn_t *gsn, int version, |
| 416 | struct sockaddr_in *peer, |
| 417 | void *pack, unsigned len); |
| 418 | |
jjako | 08d331d | 2003-10-13 20:33:30 +0000 | [diff] [blame] | 419 | extern int gtp_update_pdp_req(struct gsn_t *gsn, int version, void *cbp, |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 420 | struct in_addr *inetaddr, struct pdp_t *pdp); |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 421 | |
jjako | 08d331d | 2003-10-13 20:33:30 +0000 | [diff] [blame] | 422 | extern int gtp_delete_pdp_req(struct gsn_t *gsn, int version, void *cbp, |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 423 | struct pdp_t *pdp); |
| 424 | |
| 425 | extern int gtp_delete_pdp_resp(struct gsn_t *gsn, int version, |
jjako | 08d331d | 2003-10-13 20:33:30 +0000 | [diff] [blame] | 426 | struct sockaddr_in *peer, int fd, |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 427 | void *pack, unsigned len, |
jjako | 2c38133 | 2003-10-21 19:09:53 +0000 | [diff] [blame] | 428 | struct pdp_t *pdp, struct pdp_t *linked_pdp, |
| 429 | uint8_t cause, int teardown); |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 430 | |
| 431 | extern int gtp_delete_pdp_ind(struct gsn_t *gsn, int version, |
jjako | 08d331d | 2003-10-13 20:33:30 +0000 | [diff] [blame] | 432 | struct sockaddr_in *peer, int fd, |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 433 | void *pack, unsigned len); |
| 434 | |
| 435 | extern int gtp_delete_pdp_conf(struct gsn_t *gsn, int version, |
| 436 | struct sockaddr_in *peer, |
| 437 | void *pack, unsigned len); |
| 438 | |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 439 | extern int ipv42eua(struct ul66_t *eua, struct in_addr *src); |
| 440 | extern int eua2ipv4(struct in_addr *dst, struct ul66_t *eua); |
| 441 | extern int gsna2in_addr(struct in_addr *dst, struct ul16_t *gsna); |
| 442 | extern int in_addr2gsna(struct ul16_t *gsna, struct in_addr *src); |
Harald Welte | b10ee08 | 2017-08-12 19:29:16 +0200 | [diff] [blame] | 443 | extern const char *imsi_gtp2str(const uint64_t *imsi); |
Keith | cbc07bd | 2020-10-10 12:17:26 +0200 | [diff] [blame] | 444 | extern const uint64_t imsi_str2gtp(const char *imsi); |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 445 | |
Harald Welte | bed35df | 2011-11-02 13:06:18 +0100 | [diff] [blame] | 446 | #endif /* !_GTP_H */ |