jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 1 | /* |
| 2 | * OpenGGSN - Gateway GPRS Support Node |
| 3 | * Copyright (C) 2002 Mondru AB. |
| 4 | * |
| 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. |
| 9 | * |
| 10 | * The initial developer of the original code is |
| 11 | * Jens Jakobsen <jj@openggsn.org> |
| 12 | * |
| 13 | * Contributor(s): |
| 14 | * |
| 15 | */ |
| 16 | |
| 17 | #ifndef _GTP_H |
| 18 | #define _GTP_H |
| 19 | |
jjako | 2e840a3 | 2003-01-28 16:05:18 +0000 | [diff] [blame] | 20 | #define GTP_DEBUG 1 /* Print debug information */ |
| 21 | |
jjako | 52c2414 | 2002-12-16 13:33:51 +0000 | [diff] [blame] | 22 | #define GTP0_PORT 3386 |
| 23 | #define GTP1C_PORT 2123 |
| 24 | #define GTP1U_PORT 2152 |
| 25 | #define PACKET_MAX 8196 |
| 26 | |
| 27 | #define GTP_MAX 0xffff /* TODO: Choose right number */ |
| 28 | #define GTP0_HEADER_SIZE 20 |
| 29 | #define GTP1_HEADER_SIZE_SHORT 8 |
| 30 | #define GTP1_HEADER_SIZE_LONG 12 |
| 31 | |
| 32 | #define SYSLOG_PRINTSIZE 255 |
| 33 | #define ERRMSG_SIZE 255 |
| 34 | |
| 35 | #define RESTART_FILE "gsn_restart" |
| 36 | #define NAMESIZE 1024 |
| 37 | |
| 38 | /* GTP version 1 message type definitions. Also covers version 0 except * |
| 39 | * for anonymous PDP context which was superceded in version 1 */ |
| 40 | |
| 41 | /* 0 For future use. */ |
| 42 | #define GTP_ECHO_REQ 1 /* Echo Request */ |
| 43 | #define GTP_ECHO_RSP 2 /* Echo Response */ |
| 44 | #define GTP_NOT_SUPPORTED 3 /* Version Not Supported */ |
| 45 | #define GTP_ALIVE_REQ 4 /* Node Alive Request */ |
| 46 | #define GTP_ALIVE_RSP 5 /* Node Alive Response */ |
| 47 | #define GTP_REDIR_REQ 6 /* Redirection Request */ |
| 48 | #define GTP_REDIR_RSP 7 /* Redirection Response */ |
| 49 | /* 8-15 For future use. */ |
| 50 | #define GTP_CREATE_PDP_REQ 16 /* Create PDP Context Request */ |
| 51 | #define GTP_CREATE_PDP_RSP 17 /* Create PDP Context Response */ |
| 52 | #define GTP_UPDATE_PDP_REQ 18 /* Update PDP Context Request */ |
| 53 | #define GTP_UPDATE_PDP_RSP 19 /* Update PDP Context Response */ |
| 54 | #define GTP_DELETE_PDP_REQ 20 /* Delete PDP Context Request */ |
| 55 | #define GTP_DELETE_PDP_RSP 21 /* Delete PDP Context Response */ |
| 56 | /* 22-25 For future use. */ /* In version GTP 1 anonomous PDP context */ |
| 57 | #define GTP_ERROR 26 /* Error Indication */ |
| 58 | #define GTP_PDU_NOT_REQ 27 /* PDU Notification Request */ |
| 59 | #define GTP_PDU_NOT_RSP 28 /* PDU Notification Response */ |
| 60 | #define GTP_PDU_NOT_REJ_REQ 29 /* PDU Notification Reject Request */ |
| 61 | #define GTP_PDU_NOT_REJ_RSP 30 /* PDU Notification Reject Response */ |
| 62 | #define GTP_SUPP_EXT_HEADER 31 /* Supported Extension Headers Notification */ |
| 63 | #define GTP_SND_ROUTE_REQ 32 /* Send Routeing Information for GPRS Request */ |
| 64 | #define GTP_SND_ROUTE_RSP 33 /* Send Routeing Information for GPRS Response */ |
| 65 | #define GTP_FAILURE_REQ 34 /* Failure Report Request */ |
| 66 | #define GTP_FAILURE_RSP 35 /* Failure Report Response */ |
| 67 | #define GTP_MS_PRESENT_REQ 36 /* Note MS GPRS Present Request */ |
| 68 | #define GTP_MS_PRESENT_RSP 37 /* Note MS GPRS Present Response */ |
| 69 | /* 38-47 For future use. */ |
| 70 | #define GTP_IDEN_REQ 48 /* Identification Request */ |
| 71 | #define GTP_IDEN_RSP 49 /* Identification Response */ |
| 72 | #define GTP_SGSN_CONTEXT_REQ 50 /* SGSN Context Request */ |
| 73 | #define GTP_SGSN_CONTEXT_RSP 51 /* SGSN Context Response */ |
| 74 | #define GTP_SGSN_CONTEXT_ACK 52 /* SGSN Context Acknowledge */ |
| 75 | #define GTP_FWD_RELOC_REQ 53 /* Forward Relocation Request */ |
| 76 | #define GTP_FWD_RELOC_RSP 54 /* Forward Relocation Response */ |
| 77 | #define GTP_FWD_RELOC_COMPL 55 /* Forward Relocation Complete */ |
| 78 | #define GTP_RELOC_CANCEL_REQ 56 /* Relocation Cancel Request */ |
| 79 | #define GTP_RELOC_CANCEL_RSP 57 /* Relocation Cancel Response */ |
| 80 | #define GTP_FWD_SRNS 58 /* Forward SRNS Context */ |
| 81 | #define GTP_FWD_RELOC_ACK 59 /* Forward Relocation Complete Acknowledge */ |
| 82 | #define GTP_FWD_SRNS_ACK 60 /* Forward SRNS Context Acknowledge */ |
| 83 | /* 61-239 For future use. */ |
| 84 | #define GTP_DATA_TRAN_REQ 240 /* Data Record Transfer Request */ |
| 85 | #define GTP_DATA_TRAN_RSP 241 /* Data Record Transfer Response */ |
| 86 | /* 242-254 For future use. */ |
| 87 | #define GTP_GPDU 255 /* G-PDU */ |
| 88 | |
| 89 | /* GTP 0 header. |
| 90 | * Explanation to some of the fields: |
| 91 | * SNDCP NPDU Number flag = 0 except for inter SGSN handover situations |
| 92 | * SNDCP N-PDU LCC Number 0 = 0xff except for inter SGSN handover situations |
| 93 | * Sequence number. Used for reliable delivery of signalling messages, and |
| 94 | * to discard "illegal" data messages. |
| 95 | * Flow label. Is used to point a particular PDP context. Is used in data |
| 96 | * messages as well as signalling messages related to a particular context. |
| 97 | * Tunnel ID is IMSI+NSAPI. Unique identifier of PDP context. Is somewhat |
| 98 | * redundant because the header also includes flow. */ |
| 99 | |
| 100 | struct gtp0_header { /* Descriptions from 3GPP 09.60 */ |
| 101 | u_int8_t flags; /* 01 bitfield, with typical values */ |
| 102 | /* 000..... Version: 1 (0) */ |
| 103 | /* ...1111. Spare (7) */ |
| 104 | /* .......0 SNDCP N-PDU Number flag (0) */ |
| 105 | u_int8_t type; /* 02 Message type. T-PDU = 0xff */ |
| 106 | u_int16_t length; /* 03 Length (of G-PDU excluding header) */ |
| 107 | u_int16_t seq; /* 05 Sequence Number */ |
| 108 | u_int16_t flow; /* 07 Flow Label ( = 0 for signalling) */ |
| 109 | u_int8_t number; /* 09 SNDCP N-PDU LCC Number ( 0 = 0xff) */ |
| 110 | u_int8_t spare1; /* 10 Spare */ |
| 111 | u_int8_t spare2; /* 11 Spare */ |
| 112 | u_int8_t spare3; /* 12 Spare */ |
| 113 | u_int64_t tid; /* 13 Tunnel ID */ |
| 114 | }; /* 20 */ |
| 115 | |
| 116 | struct gtp1_header_short { /* Descriptions from 3GPP 29060 */ |
| 117 | u_int8_t flags; /* 01 bitfield, with typical values */ |
| 118 | /* 000..... Version: 1 */ |
| 119 | /* ...1.... Protocol Type: GTP=1, GTP'=0 */ |
| 120 | /* ....1... Spare = 1 */ |
| 121 | /* .....1.. Extension header flag: 1 */ |
| 122 | /* ......1. Sequence number flag: 1 */ |
| 123 | /* .......0 PN: N-PDU Number flag */ |
| 124 | u_int8_t type; /* 02 Message type. T-PDU = 0xff */ |
| 125 | u_int16_t length; /* 03 Length (of IP packet or signalling) */ |
| 126 | u_int64_t tid; /* 05 - 08 Tunnel ID */ |
| 127 | }; |
| 128 | |
| 129 | struct gtp1_header_long { /* Descriptions from 3GPP 29060 */ |
| 130 | u_int8_t flags; /* 01 bitfield, with typical values */ |
| 131 | /* 000..... Version: 1 */ |
| 132 | /* ...1.... Protocol Type: GTP=1, GTP'=0 */ |
| 133 | /* ....1... Spare = 1 */ |
| 134 | /* .....1.. Extension header flag: 1 */ |
| 135 | /* ......1. Sequence number flag: 1 */ |
| 136 | /* .......0 PN: N-PDU Number flag */ |
| 137 | u_int8_t type; /* 02 Message type. T-PDU = 0xff */ |
| 138 | u_int16_t length; /* 03 Length (of IP packet or signalling) */ |
| 139 | u_int64_t tid; /* 05 Tunnel ID */ |
| 140 | u_int16_t seq; /* 10 Sequence Number */ |
| 141 | u_int8_t npdu; /* 11 N-PDU Number */ |
| 142 | u_int8_t next; /* 12 Next extension header type. Empty = 0 */ |
| 143 | }; |
| 144 | |
| 145 | struct gtp0_packet { |
| 146 | struct gtp0_header h; |
| 147 | u_int8_t p[GTP_MAX]; |
| 148 | } __attribute__((packed)); |
| 149 | |
| 150 | struct gtp1_packet_short { |
| 151 | struct gtp1_header_short h; |
| 152 | u_int8_t p[GTP_MAX]; |
| 153 | } __attribute__((packed)); |
| 154 | |
| 155 | struct gtp1_packet_long { |
| 156 | struct gtp1_header_long h; |
| 157 | u_int8_t p[GTP_MAX]; |
| 158 | } __attribute__((packed)); |
| 159 | |
| 160 | union gtp_packet { |
| 161 | u_int8_t flags; |
| 162 | struct gtp0_packet gtp0; |
| 163 | struct gtp1_packet_short gtp1s; |
| 164 | struct gtp1_packet_long gtp1l; |
| 165 | } __attribute__((packed)) h; |
| 166 | |
| 167 | |
| 168 | |
| 169 | |
| 170 | /* *********************************************************** |
| 171 | * Information storage for each gsn instance |
| 172 | * |
| 173 | * Normally each instance of the application corresponds to |
| 174 | * one instance of a gsn. |
| 175 | * |
| 176 | * In order to avoid global variables in the application, and |
| 177 | * also in order to allow several instances of a gsn in the same |
| 178 | * application this struct is provided in order to store all |
| 179 | * relevant information related to the gsn. |
| 180 | * |
| 181 | * Note that this does not include information storage for ' |
| 182 | * each pdp context. This is stored in another struct. |
| 183 | *************************************************************/ |
| 184 | |
| 185 | struct gsn_t { |
| 186 | /* Parameters related to the network interface */ |
| 187 | |
| 188 | int fd; /* File descriptor to network interface */ |
| 189 | struct in_addr gsnc; /* IP address of this gsn for signalling */ |
| 190 | struct in_addr gsnu; /* IP address of this gsn for user traffic */ |
| 191 | |
| 192 | /* Parameters related to signalling messages */ |
| 193 | uint16_t seq_next; /* Next sequence number to use */ |
| 194 | int seq_first; /* First packet in queue (oldest timeout) */ |
| 195 | int seq_last; /* Last packet in queue (youngest timeout) */ |
| 196 | |
| 197 | unsigned char restart_counter; /* Increment on restart. Stored on disk */ |
| 198 | char *statedir; /* Disk location for permanent storage */ |
| 199 | |
| 200 | struct queue_t *queue_req; /* Request queue */ |
| 201 | struct queue_t *queue_resp; /* Response queue */ |
| 202 | |
| 203 | /* Call back functions */ |
| 204 | int (*cb_delete_context) (struct pdp_t*); |
| 205 | int (*cb_create_context) (struct pdp_t*); |
| 206 | int (*cb_conf) (int type, int cause, struct pdp_t *pdp, void* aid); |
| 207 | int (*cb_gpdu) (struct pdp_t* pdp, void* pack, unsigned len); |
| 208 | |
| 209 | /* Counters */ |
| 210 | |
| 211 | uint64_t err_socket; /* Number of socket errors */ |
| 212 | uint64_t err_readfrom; /* Number of readfrom errors */ |
| 213 | uint64_t err_sendto; /* Number of sendto errors */ |
| 214 | uint64_t err_memcpy; /* Number of memcpy */ |
| 215 | uint64_t err_queuefull; /* Number of times queue was full */ |
| 216 | uint64_t err_seq; /* Number of seq out of range */ |
| 217 | uint64_t err_address; /* GSN address conversion failed */ |
| 218 | uint64_t err_unknownpdp; /* GSN address conversion failed */ |
| 219 | uint64_t err_unknowntid; /* Application supplied unknown imsi+nsapi */ |
| 220 | uint64_t err_cause; /* Unexpected cause value received */ |
| 221 | uint64_t err_outofpdp; /* Out of storage for PDP contexts */ |
| 222 | |
| 223 | uint64_t empty; /* Number of empty packets */ |
| 224 | uint64_t unsup; /* Number of unsupported version 29.60 11.1.1 */ |
| 225 | uint64_t tooshort; /* Number of too short headers 29.60 11.1.2 */ |
| 226 | uint64_t unknown; /* Number of unknown messages 29.60 11.1.3 */ |
| 227 | uint64_t unexpect; /* Number of unexpected messages 29.60 11.1.4 */ |
| 228 | uint64_t dublicate; /* Number of dublicate or unsolicited replies */ |
| 229 | uint64_t missing; /* Number of missing mandatory field messages */ |
| 230 | uint64_t invalid; /* Number of invalid message format messages */ |
| 231 | }; |
| 232 | |
| 233 | |
| 234 | /* External API functions */ |
| 235 | |
| 236 | extern const char* gtp_version(); |
| 237 | extern int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen); |
| 238 | extern int gtp_free(struct gsn_t *gsn); |
| 239 | |
| 240 | extern int gtp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp, |
| 241 | uint64_t imsi, uint8_t nsapi); |
| 242 | extern int gtp_freepdp(struct gsn_t *gsn, struct pdp_t *pdp); |
| 243 | |
| 244 | extern int gtp_create_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid, |
| 245 | struct in_addr* inetaddr); |
| 246 | extern int gtp_update_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid, |
| 247 | struct in_addr* inetaddr); |
| 248 | extern int gtp_delete_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid); |
| 249 | |
| 250 | extern int gtp_gpdu(struct gsn_t *gsn, struct pdp_t *pdp, |
| 251 | void *pack, unsigned len); |
| 252 | |
| 253 | extern int gtp_fd(struct gsn_t *gsn); |
| 254 | extern int gtp_decaps(struct gsn_t *gsn); |
| 255 | extern int gtp_retrans(struct gsn_t *gsn); |
| 256 | extern int gtp_retranstimeout(struct gsn_t *gsn, struct timeval *timeout); |
| 257 | |
| 258 | /* |
| 259 | extern int gtp_set_cb_newpdp(struct gsn_t *gsn, |
| 260 | int (*cb) (struct pdp_t*)); |
| 261 | extern int gtp_set_cb_freepdp(struct gsn_t *gsn, |
| 262 | int (*cb) (struct pdp_t*)); |
| 263 | extern int gtp_set_cb_create_pdp_ind(struct gsn_t *gsn, |
| 264 | int (*cb) (struct pdp_t*)); |
| 265 | extern int gtp_set_cb_create_pdp_conf(struct gsn_t *gsn, |
| 266 | int (*cb) (struct pdp_t*, int)); |
| 267 | extern int gtp_set_cb_update_pdp_conf(struct gsn_t *gsn, |
| 268 | int (*cb) (struct pdp_t*, int, int)); |
| 269 | extern int gtp_set_cb_delete_pdp_ind(struct gsn_t *gsn, |
| 270 | int (*cb) (struct pdp_t*)); |
| 271 | extern int gtp_set_cb_delete_pdp_conf(struct gsn_t *gsn, |
| 272 | int (*cb) (struct pdp_t*, int)); |
| 273 | */ |
| 274 | |
| 275 | extern int gtp_set_cb_delete_context(struct gsn_t *gsn, |
| 276 | int (*cb_delete_context) (struct pdp_t* pdp)); |
| 277 | extern int gtp_set_cb_create_context(struct gsn_t *gsn, |
| 278 | int (*cb_create_context) (struct pdp_t* pdp)); |
| 279 | extern int gtp_set_cb_conf(struct gsn_t *gsn, |
| 280 | int (*cb) (int type, int cause, struct pdp_t* pdp, void *aid)); |
| 281 | extern int gtp_set_cb_gpdu(struct gsn_t *gsn, |
| 282 | int (*cb_gpdu) (struct pdp_t* pdp, void* pack, unsigned len)); |
| 283 | |
| 284 | |
| 285 | /* Internal functions (not part of the API */ |
| 286 | |
| 287 | extern int gtp_echo_req(struct gsn_t *gsn, struct in_addr *inetaddrs); |
| 288 | extern int gtp_echo_resp(struct gsn_t *gsn, struct sockaddr_in *peer, |
| 289 | void *pack, unsigned len); |
| 290 | extern int gtp_echo_ind(struct gsn_t *gsn, struct sockaddr_in *peer, |
| 291 | void *pack, unsigned len); |
| 292 | extern int gtp_echo_conf(struct gsn_t *gsn, struct sockaddr_in *peer, |
| 293 | void *pack, unsigned len); |
| 294 | |
| 295 | extern int gtp_unsup_resp(struct gsn_t *gsn, struct sockaddr_in *peer, |
| 296 | void *pack, unsigned len); |
| 297 | extern int gtp_unsup_conf(struct gsn_t *gsn, struct sockaddr_in *peer, |
| 298 | void *pack, unsigned len); |
| 299 | |
| 300 | extern int gtp_create_pdp_req(struct gsn_t *gsn, int version, void *aid, |
| 301 | struct in_addr* inetaddr, struct pdp_t *pdp); |
| 302 | |
| 303 | extern int gtp_create_pdp_resp(struct gsn_t *gsn, int version, |
| 304 | struct sockaddr_in *peer, |
| 305 | void *pack, unsigned len, |
| 306 | struct pdp_t *pdp, uint8_t cause); |
| 307 | |
| 308 | extern int gtp_create_pdp_ind(struct gsn_t *gsn, int version, |
| 309 | struct sockaddr_in *peer, |
| 310 | void *pack, unsigned len); |
| 311 | |
| 312 | extern int gtp_create_pdp_conf(struct gsn_t *gsn, int version, |
| 313 | struct sockaddr_in *peer, |
| 314 | void *pack, unsigned len); |
| 315 | |
| 316 | extern int gtp_update_pdp_req(struct gsn_t *gsn, int version, void *aid, |
| 317 | struct in_addr* inetaddr, struct pdp_t *pdp); |
| 318 | |
| 319 | extern int gtp_delete_pdp_req(struct gsn_t *gsn, int version, void *aid, |
| 320 | struct pdp_t *pdp); |
| 321 | |
| 322 | extern int gtp_delete_pdp_resp(struct gsn_t *gsn, int version, |
| 323 | struct sockaddr_in *peer, |
| 324 | void *pack, unsigned len, |
| 325 | struct pdp_t *pdp, uint8_t cause); |
| 326 | |
| 327 | extern int gtp_delete_pdp_ind(struct gsn_t *gsn, int version, |
| 328 | struct sockaddr_in *peer, |
| 329 | void *pack, unsigned len); |
| 330 | |
| 331 | extern int gtp_delete_pdp_conf(struct gsn_t *gsn, int version, |
| 332 | struct sockaddr_in *peer, |
| 333 | void *pack, unsigned len); |
| 334 | |
| 335 | |
| 336 | extern int ipv42eua(struct ul66_t *eua, struct in_addr *src); |
| 337 | extern int eua2ipv4(struct in_addr *dst, struct ul66_t *eua); |
| 338 | extern int gsna2in_addr(struct in_addr *dst, struct ul16_t *gsna); |
| 339 | extern int in_addr2gsna(struct ul16_t *gsna, struct in_addr *src); |
| 340 | |
| 341 | #endif /* !_GTP_H */ |