|
@@ -27,9 +27,19 @@
|
|
|
#include <net/sock.h>
|
|
|
#include <net/x25.h>
|
|
|
|
|
|
-/*
|
|
|
- * Parse a set of facilities into the facilities structures. Unrecognised
|
|
|
- * facilities are written to the debug log file.
|
|
|
+/**
|
|
|
+ * x25_parse_facilities - Parse facilities from skb into the facilities structs
|
|
|
+ *
|
|
|
+ * @skb: sk_buff to parse
|
|
|
+ * @facilities: Regular facilites, updated as facilities are found
|
|
|
+ * @dte_facs: ITU DTE facilities, updated as DTE facilities are found
|
|
|
+ * @vc_fac_mask: mask is updated with all facilities found
|
|
|
+ *
|
|
|
+ * Return codes:
|
|
|
+ * -1 - Parsing error, caller should drop call and clean up
|
|
|
+ * 0 - Parse OK, this skb has no facilities
|
|
|
+ * >0 - Parse OK, returns the length of the facilities header
|
|
|
+ *
|
|
|
*/
|
|
|
int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
|
|
|
struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask)
|
|
@@ -62,7 +72,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
|
|
|
switch (*p & X25_FAC_CLASS_MASK) {
|
|
|
case X25_FAC_CLASS_A:
|
|
|
if (len < 2)
|
|
|
- return 0;
|
|
|
+ return -1;
|
|
|
switch (*p) {
|
|
|
case X25_FAC_REVERSE:
|
|
|
if((p[1] & 0x81) == 0x81) {
|
|
@@ -107,7 +117,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
|
|
|
break;
|
|
|
case X25_FAC_CLASS_B:
|
|
|
if (len < 3)
|
|
|
- return 0;
|
|
|
+ return -1;
|
|
|
switch (*p) {
|
|
|
case X25_FAC_PACKET_SIZE:
|
|
|
facilities->pacsize_in = p[1];
|
|
@@ -130,7 +140,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
|
|
|
break;
|
|
|
case X25_FAC_CLASS_C:
|
|
|
if (len < 4)
|
|
|
- return 0;
|
|
|
+ return -1;
|
|
|
printk(KERN_DEBUG "X.25: unknown facility %02X, "
|
|
|
"values %02X, %02X, %02X\n",
|
|
|
p[0], p[1], p[2], p[3]);
|
|
@@ -139,18 +149,18 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
|
|
|
break;
|
|
|
case X25_FAC_CLASS_D:
|
|
|
if (len < p[1] + 2)
|
|
|
- return 0;
|
|
|
+ return -1;
|
|
|
switch (*p) {
|
|
|
case X25_FAC_CALLING_AE:
|
|
|
if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1)
|
|
|
- return 0;
|
|
|
+ return -1;
|
|
|
dte_facs->calling_len = p[2];
|
|
|
memcpy(dte_facs->calling_ae, &p[3], p[1] - 1);
|
|
|
*vc_fac_mask |= X25_MASK_CALLING_AE;
|
|
|
break;
|
|
|
case X25_FAC_CALLED_AE:
|
|
|
if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1)
|
|
|
- return 0;
|
|
|
+ return -1;
|
|
|
dte_facs->called_len = p[2];
|
|
|
memcpy(dte_facs->called_ae, &p[3], p[1] - 1);
|
|
|
*vc_fac_mask |= X25_MASK_CALLED_AE;
|